lib/jscrewit.js
function (str, options)
        {
            options = options || { };
            var optimize = options.optimize;
            var optimizerList = [];
            if (optimize)
            {
                var optimizeComplex;
                var optimizeToString;
                if (typeof optimize === 'object')
                {
                    optimizeComplex     = !!optimize.complexOpt;
                    optimizeToString    = !!optimize.toStringOpt;
                }
                else
                    optimizeComplex = optimizeToString = true;
                var optimizers = this.optimizers;
                var optimizer;
                if (optimizeComplex)
                {
                    var complexOptimizers = optimizers.complex;
                    if (!complexOptimizers)
                        complexOptimizers = optimizers.complex = createEmpty();
                    for (var complex in COMPLEX)
                    {
                        var entry = COMPLEX[complex];
                        if (this.hasFeatures(entry.mask) && str.indexOf(complex) >= 0)
                        {
                            optimizer =
                            complexOptimizers[complex] ||
                            (
                                complexOptimizers[complex] =
                                getComplexOptimizer(this, complex, entry.definition)
                            );
                            optimizerList.push(optimizer);
                        }
                    }
                }
                if (optimizeToString)
                {
                    optimizer =
                    optimizers.toString || (optimizers.toString = getToStringOptimizer(this));
                    optimizerList.push(optimizer);
                }
            }
            var buffer =
            new ScrewBuffer
            (options.bond, options.forceString, this.maxGroupThreshold, optimizerList);
            var firstSolution = options.firstSolution;
            var maxLength = options.maxLength;
            if (firstSolution)
            {
                buffer.append(firstSolution);
                if (buffer.length > maxLength)
                    return;
            }
            var match;
            var regExp = _RegExp(STR_TOKEN_PATTERN, 'g');
            while (match = regExp.exec(str))
            {
                var token;
                var solution;
                if (token = match[2])
                    solution = this.resolveCharacter(token);
                else
                {
                    token = match[1];
                    solution = SIMPLE[token];
                }
                if (!buffer.append(solution) || buffer.length > maxLength)
                    return;
            }
            var result = _String(buffer);
            if (!(result.length > maxLength))
                return result;
        }
function (str, options)
        {
            options = options || { };
            var optimize = options.optimize;
            var optimizerList = [];
            if (optimize)
            {
                var optimizeComplex;
                var optimizeToString;
                if (typeof optimize === 'object')
                {
                    optimizeComplex     = !!optimize.complexOpt;
                    optimizeToString    = !!optimize.toStringOpt;
                }
                else
                    optimizeComplex = optimizeToString = true;
                var optimizers = this.optimizers;
                var optimizer;
                if (optimizeComplex)
                {
                    var complexOptimizers = optimizers.complex;
                    if (!complexOptimizers)
                        complexOptimizers = optimizers.complex = createEmpty();
                    for (var complex in COMPLEX)
                    {
                        var entry = COMPLEX[complex];
                        if (this.hasFeatures(entry.mask) && str.indexOf(complex) >= 0)
                        {
                            optimizer =
                            complexOptimizers[complex] ||
                            (
                                complexOptimizers[complex] =
                                getComplexOptimizer(this, complex, entry.definition)
                            );
                            optimizerList.push(optimizer);
                        }
                    }
                }
                if (optimizeToString)
                {
                    optimizer =
                    optimizers.toString || (optimizers.toString = getToStringOptimizer(this));
                    optimizerList.push(optimizer);
                }
            }
            var buffer =
            new ScrewBuffer
            (options.bond, options.forceString, this.maxGroupThreshold, optimizerList);
            var firstSolution = options.firstSolution;
            var maxLength = options.maxLength;
            if (firstSolution)
            {
                buffer.append(firstSolution);
                if (buffer.length > maxLength)
                    return;
            }
            var match;
            var regExp = _RegExp(STR_TOKEN_PATTERN, 'g');
            while (match = regExp.exec(str))
            {
                var token;
                var solution;
                if (token = match[2])
                    solution = this.resolveCharacter(token);
                else
                {
                    token = match[1];
                    solution = SIMPLE[token];
                }
                if (!buffer.append(solution) || buffer.length > maxLength)
                    return;
            }
            var result = _String(buffer);
            if (!(result.length > maxLength))
                return result;
        }
function ( str , options ) { options = options || { } ; var optimize = options . optimize ; var optimizerList = [ ] ; if ( optimize ) { var optimizeComplex ; var optimizeToString ; if ( typeof optimize === 'object' ) { optimizeComplex = ! ! optimize . complexOpt ; optimizeToString = ! ! optimize . toStringOpt ; } else optimizeComplex = optimizeToString = true ; var optimizers = this . optimizers ; var optimizer ; if ( optimizeComplex ) { var complexOptimizers = optimizers . complex ; if ( ! complexOptimizers ) complexOptimizers = optimizers . complex = createEmpty ( ) ; for ( var complex in COMPLEX ) { var entry = COMPLEX [ complex ] ; if ( this . hasFeatures ( entry . mask ) && str . indexOf ( complex ) >= 0 ) { optimizer = complexOptimizers [ complex ] || ( complexOptimizers [ complex ] = getComplexOptimizer ( this , complex , entry . definition ) ) ; optimizerList . push ( optimizer ) ; } } } if ( optimizeToString ) { optimizer = optimizers . toString || ( optimizers . toString = getToStringOptimizer ( this ) ) ; optimizerList . push ( optimizer ) ; } } var buffer = new ScrewBuffer ( options . bond , options . forceString , this . maxGroupThreshold , optimizerList ) ; var firstSolution = options . firstSolution ; var maxLength = options . maxLength ; if ( firstSolution ) { buffer . append ( firstSolution ) ; if ( buffer . length > maxLength ) return ; } var match ; var regExp = _RegExp ( STR_TOKEN_PATTERN , 'g' ) ; while ( match = regExp . exec ( str ) ) { var token ; var solution ; if ( token = match [ 2 ] ) solution = this . resolveCharacter ( token ) ; else { token = match [ 1 ] ; solution = SIMPLE [ token ] ; } if ( ! buffer . append ( solution ) || buffer . length > maxLength ) return ; } var result = _String ( buffer ) ; if ( ! ( result . length > maxLength ) ) return result ; }
Replaces a given string with equivalent JSFuck code.

@function Encoder#replaceString

@param {string} str
The string to replace.

@param {object} [options={ }]
An optional object specifying replacement options.

@param {boolean} [options.bond=false]
Indicates whether the replacement expression should be bonded.

An expression is bonded if it can be treated as a single unit by any valid operators
placed immediately before or after it.
E.g. `[][[]]` is bonded but `![]` is not, because `![][[]]` is different from
`(![])[[]]`.
More exactly, a bonded expression does not contain an outer plus and does not start
with `!`.

Any expression becomes bonded when enclosed into parentheses.

@param {Solution} [options.firstSolution]
An optional solution to be prepended to the replacement string.

@param {boolean} [options.forceString=false]
Indicates whether the replacement expression should evaluate to a string.

If this parameter is falsy, the value of the replacement expression may not be equal to
the input string, but will have the same string representation.

@param {number} [options.maxLength=(NaN)]
The maximum length of the replacement expression.

If the replacement expression exceeds the specified length, the return value is
`undefined`.

If this parameter is `NaN`, then no length limit is imposed.

@param {boolean|object<string, boolean|*>} [options.optimize=false]
Specifies which optimizations should be attempted.

Optimizations may reduce the length of the replacement string, but they also reduce the
performance and may lead to unwanted circular dependencies when resolving
definitions.

This parameter can be set to a boolean value in order to turn all optimizations on
(`true`) or off (`false`).
In order to turn specific optimizations on or off, specify an object that maps
optimization names with the suffix "Opt" to booleans, or to any other optimization
specific kind of data.

@returns {string|undefined}
The replacement string or `undefined`.
Replaces a given string with equivalent JSFuck code .