Translators/DeepLTranslator: split lines beforehand (see #249)

####################################################################
# DeepLTranslator.awk                                              #
####################################################################
#
# Last Updated: 12 Dec 2017
BEGIN { provides("deepl") }

function deeplInit() {
    HttpProtocol = "http://"
    HttpHost = "www2.deepl.com"
    HttpPort = 80
}

function deeplRequestUrl(text, sl, tl, hl) {
    # Not implemented
}

function deeplTTSUrl(text, tl,    narrator) {
    # Not implemented
}

function deeplWebTranslateUrl(uri, sl, tl, hl) {
    # Not implemented
}

# Send an HTTP POST request and get response from DeepL Translator (via curl) for splitting into sentences.
function deeplPostSplit(text, sl, tl, hl,
                   ####
                   content, data, url) {
    data = "{\"jsonrpc\":\"2.0\",\"method\":\"LMT_split_into_sentences\","
    data = data "\"params\":{\"texts\":[" parameterize(text, "\"") "]}}"
    l(data)
    url = "https://www2.deepl.com/jsonrpc"
    content = curlPost(url, data)
    return assert(content, "[ERROR] Null response.")
}

# Send an HTTP POST request and get response from DeepL Translator (via curl).
function deeplPost(sentences, sl, tl, hl,
                   ####
                   content, data, i, url) {
    data = "{\"jsonrpc\":\"2.0\",\"method\":\"LMT_handle_jobs\","
    data = data "\"params\":{\"jobs\":["
    for (i in sentences) {
        if (i > 0) data = data ","
        data = data "{\"kind\":\"default\",\"raw_en_sentence\":" parameterize(sentences[i], "\"") "}"
    }
    data = data "],"
    data = data "\"lang\":{\"user_preferred_langs\":[\"" hl "\"],"
    data = data "\"source_lang_user_selected\":\"" sl "\","
    data = data "\"target_lang\":\"" tl "\"},"
    data = data "\"priority\":1},\"id\":1}"
    l(data)
    url = "https://www2.deepl.com/jsonrpc"
    content = curlPost(url, data)
    return assert(content, "[ERROR] Null response.")
}

# Get the translation of a string.
function deeplTranslate(text, sl, tl, hl,
                        isVerbose, toSpeech, returnPlaylist, returnIl,
                        ####
                        r, i, j, k, lines,
                        content, tokens, ast,
                        _sl, _tl, _hl, il,
                        sentences, translation, translations,
                        wShowOriginal, wShowTranslation,
                        wShowLanguages, wShowAlternatives,
                        group, temp) {
    if (!getCode(tl)) {
        # Check if target language is supported
        w("[WARNING] Unknown target language code: " tl)
    } else if (isRTL(tl)) {
        # Check if target language is R-to-L
        if (!FriBidi)
            w("[WARNING] " getName(tl) " is a right-to-left language, but FriBidi is not found.")
    }
    _sl = getCode(sl); if (!_sl) _sl = sl
    _tl = getCode(tl); if (!_tl) _tl = tl
    _hl = getCode(hl); if (!_hl) _hl = hl

    # Quick hack: DeepL uses uppercase language codes except for "auto"
    if (_sl != "auto") _sl = toupper(_sl)
    if (_tl != "auto") _tl = toupper(_tl)
    if (_hl != "auto") _hl = toupper(_hl)

    split(text, lines, "\n")
    for (k in lines) {
        if (k > 1) translation = translation "\n"

        delete tokens; delete ast; delete sentences

        content = deeplPostSplit(lines[k], _sl, _tl, _hl)
        tokenize(tokens, content)
        parseJson(ast, tokens)
        for (i in ast) {
            if (i ~ "^0" SUBSEP "result" SUBSEP "splitted_texts" SUBSEP "[[:digit:]]+" SUBSEP "[[:digit:]]+") {
                append(sentences, uprintf(unquote(unparameterize(ast[i]))))
            }
        }
        content = deeplPost(sentences, _sl, _tl, _hl)
        if (Option["dump"])
            return content
        tokenize(tokens, content)
        parseJson(ast, tokens)

        l(content, "content", 1, 1)
        l(tokens, "tokens", 1, 0, 1)
        l(ast, "ast")
        if (!isarray(ast) || !anything(ast)) {
            e("[ERROR] Oops! Something went wrong and I can't translate it for you :(")
            ExitCode = 1
            return
        }

        saveSortedIn = PROCINFO["sorted_in"]
        PROCINFO["sorted_in"] = "compareByIndexFields"
        j = 0
        for (i in ast) {
            if (i ~ "^0" SUBSEP "result" SUBSEP "translations" SUBSEP "[[:digit:]]+" SUBSEP "beams" \
                SUBSEP "[[:digit:]]+" SUBSEP "postprocessed_sentence$") {
                temp = uprintf(unquote(unparameterize(ast[i])))
                append(translations, temp)
            }
            if (i ~ "^0" SUBSEP "result" SUBSEP "translations" SUBSEP j SUBSEP "beams" \
                SUBSEP "[[:digit:]]+" SUBSEP "postprocessed_sentence$") {
                translation = j > 0 ? translation " " temp : translation temp
                j++
            }
        }
        PROCINFO["sorted_in"] = saveSortedIn
    }

    returnIl[0] = il = tolower(unparameterize(ast[0 SUBSEP "result" SUBSEP "source_lang"]))
    if (Option["verbose"] < -1)
        return il
    else if (Option["verbose"] < 0)
        return getList(il)

    # Generate output
    if (!isVerbose) {
        # Brief mode
        r = translation

    } else {
        # Verbose mode
        wShowOriginal = Option["show-original"]
        wShowTranslation = Option["show-translation"]
        wShowLanguages = Option["show-languages"]
        wShowAlternatives = Option["show-alternatives"]

        if (length(translations) <= 1) wShowAlternatives = 0

        if (wShowOriginal) {
            # Display: original text
            if (r) r = r RS RS
            r = r m("-- display original text")
            r = r prettify("original", s(text, il))
        }

        if (wShowTranslation) {
            # Display: major translation
            if (r) r = r RS RS
            r = r m("-- display major translation")
            r = r prettify("translation", s(translation, tl))
        }

        if (wShowLanguages) {
            # Display: source language -> target language
            if (r) r = r RS RS
            r = r m("-- display source language -> target language")
            temp = Option["fmt-languages"]
            if (!temp) temp = "[ %s -> %t ]"
            split(temp, group, /(%s|%S|%t|%T)/)
            r = r prettify("languages", group[1])
            if (temp ~ /%s/)
                r = r prettify("languages-sl", getDisplay(il))
            if (temp ~ /%S/)
                r = r prettify("languages-sl", getName(il))
            r = r prettify("languages", group[2])
            if (temp ~ /%t/)
                r = r prettify("languages-tl", getDisplay(tl))
            if (temp ~ /%T/)
                r = r prettify("languages-tl", getName(tl))
            r = r prettify("languages", group[3])
        }

        if (wShowAlternatives) {
            # Display: alternative translations
            if (r) r = r RS
            r = r m("-- display alternative translations")
            r = r RS ins(1, prettify("alternatives-translations-item", translations[1]))
            for (i = 2; i < length(translations); i++)
                r = r RS ins(1, prettify("alternatives-translations-item", translations[i]))
        }
    }

    if (toSpeech) {
        returnPlaylist[0]["text"] = translation
        returnPlaylist[0]["tl"] = tl
    }

    return r
}

####################################################################
# DeepLTranslator.awk                                              #
####################################################################
#
# Last Updated: 12 Dec 2017
BEGIN { provides("deepl") }

function deeplInit() {
    HttpProtocol = "http://"
    HttpHost = "www2.deepl.com"
    HttpPort = 80
}

function deeplRequestUrl(text, sl, tl, hl) {
    # Not implemented
}

function deeplTTSUrl(text, tl,    narrator) {
    # Not implemented
}

function deeplWebTranslateUrl(uri, sl, tl, hl) {
    # Not implemented
}

# Send an HTTP POST request and get response from DeepL Translator (via curl) for splitting into sentences.
function deeplPostSplit(text, sl, tl, hl,
                   ####
                   content, data, url) {
    data = "{\"jsonrpc\":\"2.0\",\"method\":\"LMT_split_into_sentences\","
    data = data "\"params\":{\"texts\":[" parameterize(text, "\"") "]}}"
    l(data)
    url = "https://www2.deepl.com/jsonrpc"
    content = curlPost(url, data)
    return assert(content, "[ERROR] Null response.")
}

# Send an HTTP POST request and get response from DeepL Translator (via curl).
function deeplPost(sentences, sl, tl, hl,
                   ####
                   content, data, i, url) {
    data = "{\"jsonrpc\":\"2.0\",\"method\":\"LMT_handle_jobs\","
    data = data "\"params\":{\"jobs\":["
    for (i in sentences) {
        if (i > 0) data = data ","
        data = data "{\"kind\":\"default\",\"raw_en_sentence\":" parameterize(sentences[i], "\"") "}"
    }
    data = data "],"
    data = data "\"lang\":{\"user_preferred_langs\":[\"" hl "\"],"
    data = data "\"source_lang_user_selected\":\"" sl "\","
    data = data "\"target_lang\":\"" tl "\"},"
    data = data "\"priority\":1},\"id\":1}"
    l(data)
    url = "https://www2.deepl.com/jsonrpc"
    content = curlPost(url, data)
    return assert(content, "[ERROR] Null response.")
}

# Get the translation of a string.
function deeplTranslate(text, sl, tl, hl,
                        isVerbose, toSpeech, returnPlaylist, returnIl,
                        ####
                        r, i, j,
                        content, tokens, ast,
                        _sl, _tl, _hl, il,
                        sentences, translation, translations,
                        wShowOriginal, wShowTranslation,
                        wShowLanguages, wShowAlternatives,
                        group, temp) {
    if (!getCode(tl)) {
        # Check if target language is supported
        w("[WARNING] Unknown target language code: " tl)
    } else if (isRTL(tl)) {
        # Check if target language is R-to-L
        if (!FriBidi)
            w("[WARNING] " getName(tl) " is a right-to-left language, but FriBidi is not found.")
    }
    _sl = getCode(sl); if (!_sl) _sl = sl
    _tl = getCode(tl); if (!_tl) _tl = tl
    _hl = getCode(hl); if (!_hl) _hl = hl

    # Quick hack: DeepL uses uppercase language codes except for "auto"
    if (_sl != "auto") _sl = toupper(_sl)
    if (_tl != "auto") _tl = toupper(_tl)
    if (_hl != "auto") _hl = toupper(_hl)

    content = deeplPostSplit(text, _sl, _tl, _hl)
    tokenize(tokens, content)
    parseJson(ast, tokens)
    for (i in ast) {
        if (i ~ "^0" SUBSEP "result" SUBSEP "splitted_texts" SUBSEP "[[:digit:]]+" SUBSEP "[[:digit:]]+") {
            append(sentences, uprintf(unquote(unparameterize(ast[i]))))
        }
    }
    content = deeplPost(sentences, _sl, _tl, _hl)
    if (Option["dump"])
        return content
    tokenize(tokens, content)
    parseJson(ast, tokens)

    l(content, "content", 1, 1)
    l(tokens, "tokens", 1, 0, 1)
    l(ast, "ast")
    if (!isarray(ast) || !anything(ast)) {
        e("[ERROR] Oops! Something went wrong and I can't translate it for you :(")
        ExitCode = 1
        return
    }

    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = "compareByIndexFields"
    j = 0
    for (i in ast) {
        if (i ~ "^0" SUBSEP "result" SUBSEP "translations" SUBSEP "[[:digit:]]+" SUBSEP "beams" \
            SUBSEP "[[:digit:]]+" SUBSEP "postprocessed_sentence$") {
            temp = uprintf(unquote(unparameterize(ast[i])))
            append(translations, temp)
        }
        if (i ~ "^0" SUBSEP "result" SUBSEP "translations" SUBSEP j SUBSEP "beams" \
            SUBSEP "[[:digit:]]+" SUBSEP "postprocessed_sentence$") {
            translation = j > 0 ? translation " " temp : temp
            j++
        }
    }
    PROCINFO["sorted_in"] = saveSortedIn

    returnIl[0] = il = tolower(unparameterize(ast[0 SUBSEP "result" SUBSEP "source_lang"]))
    if (Option["verbose"] < -1)
        return il
    else if (Option["verbose"] < 0)
        return getList(il)

    # Generate output
    if (!isVerbose) {
        # Brief mode
        r = translation

    } else {
        # Verbose mode
        wShowOriginal = Option["show-original"]
        wShowTranslation = Option["show-translation"]
        wShowLanguages = Option["show-languages"]
        wShowAlternatives = Option["show-alternatives"]

        if (length(translations) <= 1) wShowAlternatives = 0

        if (wShowOriginal) {
            # Display: original text
            if (r) r = r RS RS
            r = r m("-- display original text")
            r = r prettify("original", s(text, il))
        }

        if (wShowTranslation) {
            # Display: major translation
            if (r) r = r RS RS
            r = r m("-- display major translation")
            r = r prettify("translation", s(translation, tl))
        }

        if (wShowLanguages) {
            # Display: source language -> target language
            if (r) r = r RS RS
            r = r m("-- display source language -> target language")
            temp = Option["fmt-languages"]
            if (!temp) temp = "[ %s -> %t ]"
            split(temp, group, /(%s|%S|%t|%T)/)
            r = r prettify("languages", group[1])
            if (temp ~ /%s/)
                r = r prettify("languages-sl", getDisplay(il))
            if (temp ~ /%S/)
                r = r prettify("languages-sl", getName(il))
            r = r prettify("languages", group[2])
            if (temp ~ /%t/)
                r = r prettify("languages-tl", getDisplay(tl))
            if (temp ~ /%T/)
                r = r prettify("languages-tl", getName(tl))
            r = r prettify("languages", group[3])
        }

        if (wShowAlternatives) {
            # Display: alternative translations
            if (r) r = r RS
            r = r m("-- display alternative translations")
            r = r RS ins(1, prettify("alternatives-translations-item", translations[1]))
            for (i = 2; i < length(translations); i++)
                r = r RS ins(1, prettify("alternatives-translations-item", translations[i]))
        }
    }

    if (toSpeech) {
        returnPlaylist[0]["text"] = translation
        returnPlaylist[0]["tl"] = tl
    }

    return r
}


not sure what this even is...

not sure what this even is...

git-svn-id: 459970da87506910ac315916d0f5985452181198@3781 8dad8b1f-cf64-0410-95b6-bcf113ffbcfe

#! /usr/bin/awk -f

BEGIN{

    READ_SLA = 500;
    WRITE_SLA = 750;

    readcnt = 0;
    writecnt = 0;

    wlat_tot = 0;
    wlat_max = 0;
    wlat_sqtot = 0;
    wlat_slafail = 0;

    DIST_BUCKET_LENGTH = 100;
    DIST_BUCKET_COUNT = 20;
    for(i=1; i<=DIST_BUCKET_COUNT; i++)
    {
        rlat_dist[i] = 0;
        wlat_dist[i] = 0;
    }

    rlat_tot = 0;
    rlat_max = 0;
    rlat_sqtot = 0;
    rlat_slafail = 0;

    printf("READ SLA:\t%d\n", READ_SLA);
    printf("WRITE SLA:\t%d\n", WRITE_SLA);
    printf("\n");

}

/INFO - doRead()/ { readcnt = readcnt + 1;

    split(substr($0, match($0, "latency:")+ length("latency:")+1), tmp_arr, " ");
    #printf("%d\n", strtonum(tmp_arr[1]));

    lat_val = strtonum(tmp_arr[1]);

    dist_index = int(lat_val / DIST_BUCKET_LENGTH) + 1;
    if(dist_index > DIST_BUCKET_COUNT)
        dist_index = DIST_BUCKET_COUNT;
    rlat_dist[dist_index]++;

    rlat_tot = rlat_tot + lat_val;

    rlat_sqtot = rlat_sqtot + lat_val*lat_val;

    if(lat_val > rlat_max)
        rlat_max = lat_val;

    if(lat_val > READ_SLA)
        rlat_slafail = rlat_slafail + 1;

}

/INFO - doInsert()/ { writecnt = writecnt + 1;

    split(substr($0, match($0, "latency:")+ length("latency:")+1), tmp_arr, " ");

    lat_val = tmp_arr[1];

    if(index(tmp_arr[1], ",")!= 0)
        lat_val = substr(tmp_arr[1],1,index(tmp_arr[1],",")-1);

    #printf("%d\n", strtonum(lat_val));
    lat_val = strtonum(lat_val);

    dist_index = int(lat_val / DIST_BUCKET_LENGTH) + 1;
    if(dist_index > DIST_BUCKET_COUNT)
        dist_index = DIST_BUCKET_COUNT;
    wlat_dist[dist_index]++;

    wlat_tot = wlat_tot + lat_val;

    wlat_sqtot = wlat_sqtot + lat_val*lat_val;

    if(lat_val > wlat_max)
        wlat_max = lat_val;

    if(lat_val > WRITE_SLA)
        wlat_slafail = wlat_slafail + 1;

}

END{

    printf("R/W ratio:\t%.2f\n", strtonum(readcnt) / strtonum(writecnt));

    printf("\n");

    printf("#reads:\t%d\n",readcnt);
    if(strtonum(readcnt) != 0)
    {
        printf("avg read latency:\t%.2f\n", (rlat_tot / readcnt));
        printf("var read latency:\t%.2f\n", (rlat_sqtot/readcnt) - (rlat_tot/readcnt)*(rlat_tot/readcnt));
        printf("max read latency:\t%.2f\n", rlat_max);
        printf("read SLA fail:\t%d\n", rlat_slafail);

        printf("\nREAD LATENCY DISTRIBUTION\n");
        for(i=1; i<DIST_BUCKET_COUNT; i++)
            printf("\t%d - %d:\t%d\n", (i-1)*DIST_BUCKET_LENGTH, i*DIST_BUCKET_LENGTH-1, rlat_dist[i]);
        printf("\t%d - Inf:\t%d\n", (i-1)*DIST_BUCKET_LENGTH, rlat_dist[i]);
    }

    printf("\n");

    printf("#writes:\t%d\n",writecnt);
    if(strtonum(writecnt) != 0)
    {
        printf("avg write latency:\t%.2f\n", (wlat_tot / writecnt));
        printf("var write latency:\t%.2f\n", (wlat_sqtot/writecnt) - (wlat_tot/writecnt)*(wlat_tot/writecnt));
        printf("max write latency:\t%.2f\n", wlat_max);
        printf("write SLA fail:\t%d\n", wlat_slafail);

        printf("\nWRITE LATENCY DISTRIBUTION\n");
        for(i=1; i<DIST_BUCKET_COUNT; i++)
            printf("\t%d - %d:\t%d\n", (i-1)*DIST_BUCKET_LENGTH, i*DIST_BUCKET_LENGTH-1, wlat_dist[i]);
        printf("\t%d - Inf:\t%d\n", (i-1)*DIST_BUCKET_LENGTH, wlat_dist[i]);
    }

}


+ Removed search for comment and swaped \ for / in VMWARE_SCRIPT path

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
##
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
##
##    http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************

##
## convert_vmgahp_config_to_win32.awk
##
## Besed on convert_config_to_win32.awk by Todd Tannenbaum
## <tannenba@cs.wisc.edu>, 10/06
##
## Ben Burnett <burnett@cs.wisc.edu>, 12/07
##

# This is an awk script to modify condor_vmgahp_config.vmware into a form
# that with the Windows installer.  The packager on Win32 will pipe
# condor_vmgahp_config.vmware through this awk script and save it as
# condor_vmgahp_config.vmware, which is what is expected to build the
# installer.

BEGIN {
	FS = "="
}

# Set it up so we can change the VMWARE_SCRIPT option if we choose to
# do so in the installer
/^VMWARE_SCRIPT/ {
	printf "VMWARE_SCRIPT = $(BIN)/condor_vm_vmware.pl\n"
	next
}

# If we made it here, print out the line unchanged
{print $0}

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
##
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
##
##    http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************

##
## convert_vmgahp_config_to_win32.awk
##
## Besed on convert_config_to_win32.awk by Todd Tannenbaum
## <tannenba@cs.wisc.edu>, 10/06
##
## Ben Burnett <burnett@cs.wisc.edu>, 12/07
##

# This is an awk script to modify condor_vmgahp_config.vmware into a form
# that with the Windows installer.  The packager on Win32 will pipe
# condor_vmgahp_config.vmware through this awk script and save it as
# condor_vmgahp_config.vmware, which is what is expected to build the
# installer.

BEGIN {
	FS = "="
}

# Set it up so we can change the VMWARE_SCRIPT option if we choose to
# do so in the installer
/^#VMWARE_SCRIPT/ {
	printf "VMWARE_SCRIPT = $(BIN)\condor_vm_vmware.pl\n"
	next
}

# If we made it here, print out the line unchanged
{print $0}


fix pack script

fix pack script

#! /usr/bin/awk -f

BEGIN {
    placeholder="^.*{#\\s*\\S*\\s*#}.*$";
    min = ""
    if (minimized=="true") {
        min = ".min"
    }
}

$0 ~ placeholder {
    open = gensub(/{#.*$/, "", 1, $0)
    closer = gensub(/^.*#}/, "", 1, $0)

    name = gensub(/^.*{#\s*/, "", 1, $0)
    name = gensub(/\s*#}.*$/, "", 1, name)
    name = gensub(/([.]js)|([.]elm)$/, min ".js", 1, name)

    print open
    system("cat obj/" name)
    print closer
}

$0 !~ placeholder { print }

#! /usr/bin/awk -f

BEGIN {
    placeholder="^.*{#\\s*\\S*\\s*#}.*$";
    min = ""
    if (minimized=="true") {
        min = ".min"
    }
}

$0 ~ placeholder {
    open = gensub(/{#.*$/, "", 1, $0)
    name = gensub(/^.*{#\\s*/, "", 1, $0)
    name = gensub(/\\s*#}.*$/, "", 1, $0)
    name = gensub(/([.]js)|([.]elm)$/, min ".js", 1, $2)
    closer = gensub(/^.*#}/, "", 1, $0)
    print open
    system("cat obj/" name)
    print closer
}

$0 !~ placeholder { print }


URL wrangling.

URL wrangling.

BEGIN {
    print "[";
}

function printUrlQueryString(queryString)
{
    split(queryString, pairs, "&", seps)
    len = length(pairs)
    for (j = 1; j < len; ++j) {
        split(pairs[j], keyValue, "=", seps2)
        k = keyValue[1]
        v = keyValue[2]
        printf "\t\t\"%s\": \"%s\",\n", k, urlDecode(urlDecode(v))
    }
}

function base64Decode(thing)
{
  "echo "$thing" | base64 --decode" | getline x
  return x
}

function urlDecode(url) {
    for (i = 0x20; i < 0x40; ++i) {
        repl = sprintf("%c", i);
        if ((repl == "&") || (repl == "\\")) {
            repl = "\\" repl;
        }
        url = gensub(sprintf("%%%02X", i), repl, "g", url);
        url = gensub(sprintf("%%%02x", i), repl, "g", url);
    }
    return url;
}

/^#/ {
  # Ignore log comment lines
}

/^[1-9][0-9]*/ {
    date = $1                         # date
    time = $2                         # time
    x_edge_location = $3              # x-edge-location
    sc_bytes = $4                     # sc-bytes
    c_ip = $5                         # c-ip
    cs_method = $6                    # cs-method
    cs_Host = $7                      # cs(Host)
    cs_uri_stem = $8                  # cs-uri-stem
    sc_status = $9                    # sc-status
    cs_Referer = $10                  # cs(Referer)
    cs_User_Agent = $11               # cs(User-Agent)
    cs_uri_query = $12                # cs-uri-query
    cs_Cookie = $13                   # cs(Cookie)
    x_edge_result_type = $14          # x-edge-result-type
    x_edge_request_id = $15           # x-edge-request-id
    x_host_header = $16               # x-host-header
    cs_protocol = $17                 # cs-protocol
    cs_bytes = $18                    # cs-bytes
    time_taken = $19                  # time-taken
    x_forwarded_for = $20             # x-forwarded-for
    ssl_protocol = $21                # ssl-protocol
    ssl_cipher = $22                  # ssl-cipher
    x_edge_response_result_type = $23 # x-edge-response-result-type
    printf "{\n\t\"date\": \"%s\",\n\t\"time\":\"%s\",\n\t\"x-edge-location\":\"\%s\",\n\t\"sc-bytes\": \"%s\",\n\t\"c-ip\": \"%s\",\n\t\"cs-method\": \"%s\",\n\t\"cs(Host)\": \"%s\",\n\t\"cs-uri-stream\": \"%s\",\n\t\"sc-status\": \"%s\",\n\t\"cs(Referer)\": \"%s\",\n\t\"cs(User-Agent)\": \"%s\",\n\t\"cs(Cookie)\": \"%s\",\n\t\"x-edge-result-type\": \"%s\",\n\t\"x-edge-request-id\": \"%s\",\n\t\"x-host-header\": \"%s\"\n\t\"cs-protocol\": \"%s\",\n\t\"cs-bytes\": \"%s\",\n\t\"time-taken\": \"%s\",\n\t\"x-forwarded-for\": \"%s\",\n\t\"ssl-protocol\": \"%s\",\n\t\"ssl-cipher\": \"%s\",\n\t\"x-edge-response-result-type\": \"%s\",\n", date, time, x_edge_location, sc_bytes, c_ip, cs_method, cs_Host, cs_uri_stem, sc_status, cs_Referer, urlDecode(urlDecode(cs_User_Agent)), cs_Cookie, x_edge_result_type, x_edge_request_id, x_host_header, cs_protocol, cs_bytes, time_taken, x_forwarded_for, ssl_protocol, ssl_cipher, x_edge_response_result_type
  printf "\t\"cs-uri-query\": {\n"
  printUrlQueryString(cs_uri_query)
  printf "\t}\n"
}

END {
  print "]";
}

BEGIN {
    print "[";
}

/^#/ {
  # Ignore log comment lines
}

/^[1-9][0-9]*/ {
    date = $1                         # date
    time = $2                         # time
    x_edge_location = $3              # x-edge-location
    sc_bytes = $4                     # sc-bytes
    c_ip = $5                         # c-ip
    cs_method = $6                    # cs-method
    cs_Host = $7                      # cs(Host)
    cs_uri_stem = $8                  # cs-uri-stem
    sc_status = $9                    # sc-status
    cs_Referer = $10                  # cs(Referer)
    cs_User_Agent = $11               # cs(User-Agent)
    cs_uri_query = $12                # cs-uri-query
    cs_Cookie = $13                   # cs(Cookie)
    x_edge_result_type = $14          # x-edge-result-type
    x_edge_request_id = $15           # x-edge-request-id
    x_host_header = $16               # x-host-header
    cs_protocol = $17                 # cs-protocol
    cs_bytes = $18                    # cs-bytes
    time_taken = $19                  # time-taken
    x_forwarded_for = $20             # x-forwarded-for
    ssl_protocol = $21                # ssl-protocol
    ssl_cipher = $22                  # ssl-cipher
    x_edge_response_result_type = $23 # x-edge-response-result-type
    printf "{\n\t\"date\": \"%s\",\n\t\"time\":\"%s\",\n\t\"x-edge-location\":\"\%s\",\n\t\"sc-bytes\": \"%s\",\n\t\"c-ip\": \"%s\",\n\t\"cs-method\": \"%s\",\n\t\"cs(Host)\": \"%s\",\n\t\"cs-uri-stream\": \"%s\",\n\t\"sc-status\": \"%s\",\n\t\"cs(Referer)\": \"%s\",\n\t\"cs(User-Agent)\": \"%s\",\n\t\"cs-uri-query\": \"%s\",\n\t\"cs(Cookie)\": \"%s\",\n\t\"x-edge-result-type\": \"%s\",\n\t\"x-edge-request-id\": \"%s\",\n\t\"x-host-header\": \"%s\"\n\t\"cs-protocol\": \"%s\",\n\t\"cs-bytes\": \"%s\",\n\t\"time-taken\": \"%s\",\n\t\"x-forwarded-for\": \"%s\",\n\t\"ssl-protocol\": \"%s\",\n\t\"ssl-cipher\": \"%s\",\n\t\"x-edge-response-result-type\": \"%s\"\n},\n", date, time, x_edge_location, sc_bytes, c_ip, cs_method, cs_Host, cs_uri_stem, sc_status, cs_Referer, cs_User_Agent, cs_uri_query, cs_Cookie, x_edge_result_type, x_edge_request_id, x_host_header, cs_protocol, cs_bytes, time_taken, x_forwarded_for, ssl_protocol, ssl_cipher, x_edge_response_result_type
}

END {
  print "]";
}


GenTK: cache TK

GenTK: cache TK


Remove some debug output.

Remove some debug output.

# translate flatzinc format to python/Numberjack

BEGIN {
	MAXINT = 10000000;
	print "#! /usr/bin/env python"
	print "import time"
	print "from Numberjack import *"
	system("cat " MZNNJ_DIR "/fzn2py.py");
	print "";
	print "def get_model():"
	print "    model = Model()";
	parameter = 1;
	error = 0;
}

# { print $0 } # for debugging purposes only

/::_output_var/ {
	gsub("::_output_var","");
	$0 = $0 " ::_output_";
}

/::_output_array/ {
	regexp = "::_output_array[(][[](range[(][0-9]+,1[+][0-9]+[)][ ,]*)+[]][)]";
	if (match($0,regexp)) {
	  array = substr($0, RSTART, RLENGTH);
	  sub(regexp,"");
	  gsub("[[]","",array);
	  gsub("[]]","",array);
	  gsub(" ","",array);
	  gsub("range[(]","",array);
	  gsub(",1[+]","..",array);
	  gsub("[)]","",array);
	  nbdim = array;
	  gsub("[^,]","",nbdim);
	  dim = length(nbdim)+1;
	  sub("::_output_array", "array" dim "d",array);
	  $0 = $0 " ::_output_" array;
	} else {
		print "ERROR WRONG OUTPUT ARRAY DEFINITION",$0;
		error = 3;
		exit(2);
	}
}

/^var / {
	parameter = 0;
}

/ of var / {
	parameter = 0;
}

parameter {
	sub(".*: ","");
	if ($2 == "=") print "    " $0; # it might be a predicate instead if no =
}

/^var bool:/{
	print "    " $3 " = Variable('" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^var int:/{
	print "    " $3 " = Variable(-" MAXINT "," MAXINT ",'" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^var range[(][-]*[0-9]+,1[+][-]*[0-9]+[)]:/{
	sub("range[(]","",$2);
	sub("[)]:","",$2);
	sub(",1[+]",",",$2);
	print "    " $3 " = Variable(" $2 ",'" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^var {[-]*[0-9]+(,[-]*[0-9]+)*}:/{
	sub("{","[",$2);
	sub("}:","]",$2);
	print "    " $3 " = Variable(" $2 ",'" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var bool:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	name = $6;
	print "    " name " = VarArray(" isup ",'" name "')";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var int:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	name = $6;
	print "    " name " = VarArray(" isup ",-" MAXINT "," MAXINT ",'" name "')";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var range[(][-]*[0-9]+,1[+][-]*[0-9]+[)]:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	sub("range[(]","",$5);
	sub("[)]:","",$5);
	sub(",1[+]",",",$5);
	name = $6;
	print "    " name " = VarArray(" isup "," $5 ",'" name "')";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var {[-]*[0-9]+(,[-]*[0-9]+)*}:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	sub("{","[",$5);
	sub("}:","]",$5);
	name = $6;
	print "    " name " = [Variable(" $5 ",'" name "_" i "') for i in range(" isup ")]";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^constraint /{
	$1 = "    model.add(";
    	$NF = $NF " )";
	print $0;
}

/^solve / && / minimize /{
	print "    model.add(Minimize(" $NF "))";
	objective = $NF;
}

/^solve / && / maximize /{
	print "    model.add(Maximize(" $NF "))";
	objective = $NF;
}

END {
	if (!error) {
	output_vars = "";
	if(objective) output_vars = objective;

	n = asorti(output,varnames);
	for (i=1; i<=n; i++) {
		e = varnames[i];
		if(e != objective) {
			if(length(output_vars) > 0) output_vars = output_vars ", ";
			output_vars = output_vars e;
		}
	}
	print "    output_vars = (" output_vars ")";
	print "    return model, output_vars";

	print "";
	print "model, output_vars = get_model()";
	if(output_vars) print output_vars " = output_vars";
	print "solvers = ['Mistral', 'SCIP', 'MiniSat', 'Toulbar2', 'Gurobi']";
	print "default = dict([('solver', 'Mistral'), ('verbose', 0), ('tcutoff', 900), ('var', 'DomainOverWDegree'), ('val', 'Lex'), ('rand', 2), ('threads', 1), ('restart', GEOMETRIC), ('base', 256), ('factor', 1.3)])";
	print "param = input(default)";
	print "solver = model.load(param['solver'])";
	print "solver.setVerbosity(param['verbose'])";
	print "solver.setTimeLimit(param['tcutoff'] - int(time.clock()+0.5))";
	print "solver.setHeuristic(param['var'], param['val'], param['rand'])";
	print "if param['solver'] == 'Gurobi':";
	print "    solver.setThreadCount(param['threads'])";
	print "if param['solver'] == 'Mistral':";
	print "    # LUBY, GEOMETRIC = 0, 1"
	print "    solver.solveAndRestart(param['restart'], param['base'], param['factor'])";
	print "else:";
	print "    solver.solve()";
	print "if solver.is_sat():"
	for (i=1; i<=n; i++) {
		e = varnames[i];
		if (output[e]==1) {
			if (e != objective && e != "objective" && e != "obj") print "    print '" e " = '," e ".get_value(),';'";
			else print "    print '" e " = ', (solver.getOptimum() if param['solver'] == 'Toulbar2' else " e ".get_value()),';'";
		} else {
			print "    print '" e " = " outputstring[e] ",',str(" e "),');'";
		}
	}
	print "    print '----------'";
	if (objective){
		print "    if solver.is_opt():"
		print "        print '=========='"
	} else {
		print "    print '=========='"
	}
	print "elif solver.is_unsat():"
	print "    print '=====UNSATISFIABLE====='"
    print "else:"
	print "    print '=====UNKNOWN====='"
	print "print '% SolveTime', solver.getTime()";
	print "print '% Nodes', solver.getNodes()";
	print "print '% Failures', solver.getFailures()";
	if (objective) print "if solver.is_sat(): print '% Objective', (solver.getOptimum() if param['solver'] == 'Toulbar2' else " objective ".get_value())";
	}
}

# translate flatzinc format to python/Numberjack

BEGIN {
	MAXINT = 10000000;
	print "#! /usr/bin/env python"
	print "import time"
	print "from Numberjack import *"
	system("cat " MZNNJ_DIR "/fzn2py.py");
	print "";
	print "def get_model():"
	print "    model = Model()";
	parameter = 1;
	error = 0;
}

# { print $0 } # for debugging purposes only

/::_output_var/ {
	gsub("::_output_var","");
	$0 = $0 " ::_output_";
}

/::_output_array/ {
	regexp = "::_output_array[(][[](range[(][0-9]+,1[+][0-9]+[)][ ,]*)+[]][)]";
	if (match($0,regexp)) {
	  array = substr($0, RSTART, RLENGTH);
	  sub(regexp,"");
	  gsub("[[]","",array);
	  gsub("[]]","",array);
	  gsub(" ","",array);
	  gsub("range[(]","",array);
	  gsub(",1[+]","..",array);
	  gsub("[)]","",array);
	  nbdim = array;
	  gsub("[^,]","",nbdim);
	  dim = length(nbdim)+1;
	  sub("::_output_array", "array" dim "d",array);
	  $0 = $0 " ::_output_" array;
	} else {
		print "ERROR WRONG OUTPUT ARRAY DEFINITION",$0;
		error = 3;
		exit(2);
	}
}

/^var / {
	parameter = 0;
}

/ of var / {
	parameter = 0;
}

parameter {
	sub(".*: ","");
	if ($2 == "=") print "    " $0; # it might be a predicate instead if no =
}

/^var bool:/{
	print "    " $3 " = Variable('" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^var int:/{
	print "    " $3 " = Variable(-" MAXINT "," MAXINT ",'" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^var range[(][-]*[0-9]+,1[+][-]*[0-9]+[)]:/{
	sub("range[(]","",$2);
	sub("[)]:","",$2);
	sub(",1[+]",",",$2);
	print "    " $3 " = Variable(" $2 ",'" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^var {[-]*[0-9]+(,[-]*[0-9]+)*}:/{
	sub("{","[",$2);
	sub("}:","]",$2);
	print "    " $3 " = Variable(" $2 ",'" $3 "')";
	if (match($0,"::_output_")) output[$3] = 1;
	if ($4 == "=") print "    model.add(" $3 " == " $5 ")";
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var bool:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	name = $6;
	print "    " name " = VarArray(" isup ",'" name "')";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var int:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	name = $6;
	print "    " name " = VarArray(" isup ",-" MAXINT "," MAXINT ",'" name "')";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var range[(][-]*[0-9]+,1[+][-]*[0-9]+[)]:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	sub("range[(]","",$5);
	sub("[)]:","",$5);
	sub(",1[+]",",",$5);
	name = $6;
	print "    " name " = VarArray(" isup "," $5 ",'" name "')";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^array [[]range[(][-]*[0-9]+,1[+][-]*[0-9]+[)][]] of var {[-]*[0-9]+(,[-]*[0-9]+)*}:/{
	sub("[[]range[(]","",$2);
	sub("[)][]]","",$2);
	sub(",1[+]",",",$2);
	iinf = $2;
	sub(",.*","",iinf);
	if (iinf != 1) {
		print "ERROR ASSUMING MINIMUM INDEX VALUE EQUAL TO ONE IN ARRAY DEFINITION",$0;
		error = 1;
		exit(1);
	}
	isup = $2;
	sub(".*,","",isup);
	if (isup < iinf) {
		print "ERROR WRONG RANGE INDEX VALUE IN ARRAY DEFINITION",$0;
		error = 2;
		exit(2);
	}
	sub("{","[",$5);
	sub("}:","]",$5);
	name = $6;
	print "    " name " = [Variable(" $5 ",'" name "_" i "') for i in range(" isup ")]";
	if (match($0,"::_output_")) {
		output[ name ] = isup;
		outputstring[ name ] = substr($0, RSTART+RLENGTH);
	}
	if ($7 == "=") {
		sub(".*= ","");
		sub("::_output_.*","");
		gsub(" ","");
		for (i=0; i<isup; i++) {
			print "    model.add(" name "[" i "] == " $0 "[" i "])";
		}
	}
}

/^constraint /{
	$1 = "    model.add(";
    	$NF = $NF " )";
	print $0;
}

/^solve / && / minimize /{
	print "    model.add(Minimize(" $NF "))";
	objective = $NF;
}

/^solve / && / maximize /{
	print "    model.add(Maximize(" $NF "))";
	objective = $NF;
}

END {
	if (!error) {
	output_vars = "";
	if(objective) output_vars = objective;

	n = asorti(output,varnames);
	for (i=1; i<=n; i++) {
		e = varnames[i];
		if(e != objective) {
			if(length(output_vars) > 0) output_vars = output_vars ", ";
			output_vars = output_vars e;
		}
	}
	print "    output_vars = (" output_vars ")";
	print "    return model, output_vars";

	print "";
	print "model, output_vars = get_model()";
	if(output_vars) print output_vars " = output_vars";
	print "solvers = ['Mistral', 'SCIP', 'MiniSat', 'Toulbar2', 'Gurobi']";
	print "default = dict([('solver', 'Mistral'), ('verbose', 0), ('tcutoff', 900), ('var', 'DomainOverWDegree'), ('val', 'Lex'), ('rand', 2), ('threads', 1), ('restart', GEOMETRIC), ('base', 256), ('factor', 1.3)])";
	print "param = input(default)";
	print "solver = model.load(param['solver'])";
	print "solver.setVerbosity(param['verbose'])";
	print "solver.setTimeLimit(param['tcutoff'] - int(time.clock()+0.5))";
	print "solver.setHeuristic(param['var'], param['val'], param['rand'])";
	print "if param['solver'] == 'Gurobi':";
	print "    solver.setThreadCount(param['threads'])";
	print "if param['solver'] == 'Mistral':";
	print "    # LUBY, GEOMETRIC = 0, 1"
	print "    print '%% running Mistral with restarts: %d %d %.1f' % (param['restart'], param['base'], param['factor'])";
	#print "    solver.solveAndRestart(GEOMETRIC, 256, 1.3)";
	print "    solver.solveAndRestart(param['restart'], param['base'], param['factor'])";
	print "else:";
	print "    solver.solve()";
	print "if solver.is_sat():"
	for (i=1; i<=n; i++) {
		e = varnames[i];
		if (output[e]==1) {
			if (e != objective && e != "objective" && e != "obj") print "    print '" e " = '," e ".get_value(),';'";
			else print "    print '" e " = ', (solver.getOptimum() if param['solver'] == 'Toulbar2' else " e ".get_value()),';'";
		} else {
			print "    print '" e " = " outputstring[e] ",',str(" e "),');'";
		}
	}
	print "    print '----------'";
	if (objective){
		print "    if solver.is_opt():"
		print "        print '=========='"
	} else {
		print "    print '=========='"
	}
	print "elif solver.is_unsat():"
	print "    print '=====UNSATISFIABLE====='"
    print "else:"
	print "    print '=====UNKNOWN====='"
	print "print '% SolveTime', solver.getTime()";
	print "print '% Nodes', solver.getNodes()";
	print "print '% Failures', solver.getFailures()";
	if (objective) print "if solver.is_sat(): print '% Objective', (solver.getOptimum() if param['solver'] == 'Toulbar2' else " objective ".get_value())";
	}
}


Help: reimplement getReference()

Help: reimplement getReference()

####################################################################
# Help.awk                                                         #
####################################################################

# Return version as a string.
function getVersion(    build, gitHead, platform) {
    initAudioPlayer()
    initPager()
    platform = detectProgram("uname", "-o", 1)
    if (ENVIRON["TRANS_BUILD"])
        build = "-" ENVIRON["TRANS_BUILD"]
    else {
        gitHead = getGitHead()
        build = gitHead ? "-git:" gitHead : ""
    }

    return sprintf(ansi("bold", "%-22s%s%s") "\n\n", Name, Version, build) \
        sprintf("%-22s%s\n", "platform", platform)                      \
        sprintf("%-22s%s\n", "gawk (GNU Awk)", PROCINFO["version"])     \
        sprintf("%s\n", FriBidi ? FriBidi :
                "fribidi (GNU FriBidi) [NOT INSTALLED]")                \
        sprintf("%-22s%s\n", "audio player", AudioPlayer ? AudioPlayer :
                "[NOT INSTALLED]")                                      \
        sprintf("%-22s%s\n", "terminal pager", Pager ? Pager :
                "[NOT INSTALLED]")                                      \
        sprintf("%-22s%s\n", "terminal type", ENVIRON["TERM"])          \
        sprintf("%-22s%s (%s)\n", "user locale", UserLocale, getName(UserLang)) \
        sprintf("%-22s%s\n", "home language", Option["hl"])             \
        sprintf("%-22s%s\n", "source language", Option["sl"])           \
        sprintf("%-22s%s\n", "target language", join(Option["tl"], "+")) \
        sprintf("%-22s%s\n", "theme", Option["theme"])                  \
        sprintf("%-22s%s\n", "init file", InitScript ? InitScript : "[NONE]") \
        sprintf("\n%-22s%s", "Report bugs to:", "https://github.com/soimort/translate-shell/issues")
}

# Return help message as a string.
function getHelp() {
    return "Usage:  " ansi("bold", Command)                             \
        " [" ansi("underline", "OPTIONS") "]"                           \
        " [" ansi("underline", "SOURCE") "]"                            \
        ":[" ansi("underline", "TARGETS") "]"                           \
        " [" ansi("underline", "TEXT") "]..." RS                        \
        RS "Information options:" RS                                    \
        ins(1, ansi("bold", "-V") ", " ansi("bold", "-version")) RS     \
        ins(2, "Print version and exit.") RS                            \
        ins(1, ansi("bold", "-H") ", " ansi("bold", "-help")) RS        \
        ins(2, "Print help message and exit.") RS                       \
        ins(1, ansi("bold", "-M") ", " ansi("bold", "-man")) RS         \
        ins(2, "Show man page and exit.") RS                            \
        ins(1, ansi("bold", "-T") ", " ansi("bold", "-reference")) RS   \
        ins(2, "Print reference table of languages and exit.") RS       \
        ins(1, ansi("bold", "-R") ", " ansi("bold", "-reference-english")) RS \
        ins(2, "Print reference table of languages (in English names) and exit.") RS \
        ins(1, ansi("bold", "-L ") ansi("underline", "CODES")           \
            ", " ansi("bold", "-list ") ansi("underline", "CODES")) RS  \
        ins(2, "Print details of languages and exit.") RS               \
        ins(1, ansi("bold", "-U") ", " ansi("bold", "-upgrade")) RS     \
        ins(2, "Upgrade this program to latest version.") RS            \
        RS "Display options:" RS                                        \
        ins(1, ansi("bold", "-verbose")) RS                             \
        ins(2, "Verbose mode. (default)") RS                            \
        ins(1, ansi("bold", "-b") ", " ansi("bold", "-brief")) RS       \
        ins(2, "Brief mode.") RS                                        \
        ins(1, ansi("bold", "-d") ", " ansi("bold", "-dictionary")) RS  \
        ins(2, "Dictionary mode.") RS                                   \
        ins(1, ansi("bold", "-show-original ") ansi("underline", "Y/n")) RS \
        ins(2, "Show original text or not.") RS                         \
        ins(1, ansi("bold", "-show-original-phonetics ") ansi("underline", "Y/n")) RS \
        ins(2, "Show phonetic notation of original text or not.") RS    \
        ins(1, ansi("bold", "-show-translation ") ansi("underline", "Y/n")) RS \
        ins(2, "Show translation or not.") RS                           \
        ins(1, ansi("bold", "-show-translation-phonetics ") ansi("underline", "Y/n")) RS \
        ins(2, "Show phonetic notation of translation or not.") RS      \
        ins(1, ansi("bold", "-show-prompt-message ") ansi("underline", "Y/n")) RS \
        ins(2, "Show prompt message or not.") RS                        \
        ins(1, ansi("bold", "-show-languages ") ansi("underline", "Y/n")) RS \
        ins(2, "Show source and target languages or not.") RS           \
        ins(1, ansi("bold", "-show-original-dictionary ") ansi("underline", "y/N")) RS \
        ins(2, "Show dictionary entry of original text or not.") RS     \
        ins(1, ansi("bold", "-show-dictionary ") ansi("underline", "Y/n")) RS \
        ins(2, "Show dictionary entry of translation or not.") RS       \
        ins(1, ansi("bold", "-show-alternatives ") ansi("underline", "Y/n")) RS \
        ins(2, "Show alternative translations or not.") RS              \
        ins(1, ansi("bold", "-w ") ansi("underline", "NUM")             \
            ", " ansi("bold", "-width ") ansi("underline", "NUM")) RS   \
        ins(2, "Specify the screen width for padding.") RS              \
        ins(1, ansi("bold", "-indent ") ansi("underline", "NUM")) RS    \
        ins(2, "Specify the size of indent (number of spaces).") RS     \
        ins(1, ansi("bold", "-theme ") ansi("underline", "FILENAME")) RS \
        ins(2, "Specify the theme to use.") RS                          \
        ins(1, ansi("bold", "-no-theme")) RS                            \
        ins(2, "Do not use any other theme than default.") RS           \
        ins(1, ansi("bold", "-no-ansi")) RS                             \
        ins(2, "Do not use ANSI escape codes.") RS                      \
        RS "Audio options:" RS                                          \
        ins(1, ansi("bold", "-p, -play")) RS                            \
        ins(2, "Listen to the translation.") RS                         \
        ins(1, ansi("bold", "-player ") ansi("underline", "PROGRAM")) RS \
        ins(2, "Specify the audio player to use, and listen to the translation.") RS \
        ins(1, ansi("bold", "-no-play")) RS                             \
        ins(2, "Do not listen to the translation.") RS                  \
        RS "Terminal paging and browsing options:" RS                   \
        ins(1, ansi("bold", "-v") ", " ansi("bold", "-view")) RS        \
        ins(2, "View the translation in a terminal pager.") RS          \
        ins(1, ansi("bold", "-pager ") ansi("underline", "PROGRAM")) RS \
        ins(2, "Specify the terminal pager to use, and view the translation.") RS \
        ins(1, ansi("bold", "-no-view")) RS                             \
        ins(2, "Do not view the translation in a terminal pager.") RS   \
        ins(1, ansi("bold", "-browser ") ansi("underline", "PROGRAM")) RS \
        ins(2, "Specify the web browser to use.") RS                    \
        RS "Networking options:" RS                                     \
        ins(1, ansi("bold", "-x ") ansi("underline", "HOST:PORT")       \
            ", " ansi("bold", "-proxy ") ansi("underline", "HOST:PORT")) RS \
        ins(2, "Use HTTP proxy on given port.") RS                      \
        ins(1, ansi("bold", "-u ") ansi("underline", "STRING")          \
            ", " ansi("bold", "-user-agent ") ansi("underline", "STRING")) RS \
        ins(2, "Specify the User-Agent to identify as.") RS             \
        RS "Interactive shell options:" RS                              \
        ins(1, ansi("bold", "-I") ", " ansi("bold", "-interactive") ", " ansi("bold", "-shell")) RS \
        ins(2, "Start an interactive shell.") RS                        \
        ins(1, ansi("bold", "-E") ", " ansi("bold", "-emacs")) RS       \
        ins(2, "Start the GNU Emacs front-end for an interactive shell.") RS \
        ins(1, ansi("bold", "-no-rlwrap")) RS                           \
        ins(2, "Do not invoke rlwrap when starting an interactive shell.") RS \
        RS "I/O options:" RS                                            \
        ins(1, ansi("bold", "-i ") ansi("underline", "FILENAME")        \
            ", " ansi("bold", "-input ") ansi("underline", "FILENAME")) RS \
        ins(2, "Specify the input file.") RS                            \
        ins(1, ansi("bold", "-o ") ansi("underline", "FILENAME")        \
            ", " ansi("bold", "-output ") ansi("underline", "FILENAME")) RS \
        ins(2, "Specify the output file.") RS                           \
        RS "Language preference options:" RS                            \
        ins(1, ansi("bold", "-l ") ansi("underline", "CODE")            \
            ", " ansi("bold", "-lang ") ansi("underline", "CODE")) RS   \
        ins(2, "Specify your home language.") RS                        \
        ins(1, ansi("bold", "-s ") ansi("underline", "CODE")            \
            ", " ansi("bold", "-source ") ansi("underline", "CODE")) RS \
        ins(2, "Specify the source language.") RS                       \
        ins(1, ansi("bold", "-t ") ansi("underline", "CODES")           \
            ", " ansi("bold", "-target ") ansi("underline", "CODES")) RS \
        ins(2, "Specify the target language(s), joined by '+'.") RS     \
        RS "Other options:" RS                                          \
        ins(1, ansi("bold", "-no-init")) RS                             \
        ins(2, "Do not load any initialization script.") RS             \
        RS "See the man page " Command "(1) for more information."
}

# Show man page.
function showMan(    temp) {
    if (ENVIRON["TRANS_MANPAGE"]) {
        initPager()
        Groff = detectProgram("groff", "--version")
        if (Pager && Groff) {
            temp = "echo -E \"${TRANS_MANPAGE}\""
            temp = temp PIPE                                            \
                Groff " -Wall -mtty-char -mandoc -Tutf8 "               \
                "-rLL=" Option["width"] "n -rLT=" Option["width"] "n"
            switch (Pager) {
            case "less":
                temp = temp PIPE                                        \
                    Pager " -s -P\"\\ \\Manual page " Command "(1) line %lt (press h for help or q to quit)\""
                break
            case "most":
                temp = temp PIPE Pager " -Cs"
                break
            default: # more
                temp = temp PIPE Pager
            }
            system(temp)
            return
        }
    }
    if (fileExists("man/" Command ".1"))
        system("man man/" Command ".1" SUPERR)
    else if (system("man " Command SUPERR))
        print getHelp()
}

# Comparator using getName().
function compName(i1, v1, i2, v2) {
    if (getName(i1) < getName(i2)) return -1
    else return (getName(i1) != getName(i2))
}

# Return a reference table of languages as a string.
# Parameters:
#     displayName = "endonym" or "name"
function getReference(displayName,
                      ####
                      code, col, cols, i, j, name, rows, r, saveSortedIn, t, tt) {
    rows = int(length(Locale) / 3) + 1
    cols[0][0] = cols[1][0] = cols[2][0] = NULLSTR
    i = 0
    saveSortedIn = PROCINFO["sorted_in"]
    PROCINFO["sorted_in"] = displayName == "endonym" ? "@ind_num_asc" :
        "compName"
    for (code in Locale) {
        col = int(i / rows)
        append(cols[col], code)
        i++
    }
    PROCINFO["sorted_in"] = saveSortedIn

    if (displayName == "endonym") {
        r = "┌" replicate("─", 22) "┬" replicate("─", 23) "┬" replicate("─", 23) "┐" RS
        for (i = 0; i < rows; i++) {
            r = r "│ "
            for (j = 0; j < 3; j++) {
                if (cols[j][i]) {
                    t = cols[j][i] == "he" ||
                        cols[j][i] == "hi" ||
                        cols[j][i] == "hu" ||
                        cols[j][i] == "la" ||
                        cols[j][i] == "ml" ||
                        cols[j][i] == "mn" ||
                        cols[j][i] == "ne" ||
                        cols[j][i] == "ny" ||
                        cols[j][i] == "pa" ||
                        cols[j][i] == "pl" ||
                        cols[j][i] == "ro" ||
                        cols[j][i] == "sr" ||
                        cols[j][i] == "te" ||
                        cols[j][i] == "tg" ||
                        cols[j][i] == "tr" ||
                        cols[j][i] == "ur" ||
                        cols[j][i] == "yi" ||
                        cols[j][i] == "yo" ||
                        (cols[j][i] != "zh-CN" && cols[j][i] != "zh-TW" &&
                         length(getEndonym(cols[j][i])) < 6) ? "\t\t " :
                        cols[j][i] == "ht" ? " " :
                        cols[j][i] == "id" ? "" :
                        "\t "
                    tt = length(cols[j][i]) == 3 ? " │" :
                        (cols[j][i] != "zh-CN" && cols[j][i] != "zh-TW") ? "  │" : ""
                    r = r getDisplay(cols[j][i]) t "- " ansi("bold", cols[j][i]) tt " "
                } else
                    r = r "\t\t       │"
            }
            r = r RS
        }
        r = r "└" replicate("─", 22) "┴" replicate("─", 23) "┴" replicate("─", 23) "┘"
    } else {
        r = "┌" replicate("─", 22) "┬" replicate("─", 23) "┬" replicate("─", 23) "┐" RS
        for (i = 0; i < rows; i++) {
            r = r "│ "
            for (j = 0; j < 3; j++) {
                if (cols[j][i]) {
                    t = cols[j][i] == "he" ||
                        cols[j][i] == "kk" ||
                        cols[j][i] == "ko" ||
                        cols[j][i] == "ne" ||
                        cols[j][i] == "pl" ||
                        cols[j][i] == "sk" ||
                        cols[j][i] == "so" ||
                        cols[j][i] == "te" ||
                        cols[j][i] == "yo" ||
                        (cols[j][i] != "zh-CN" && cols[j][i] != "zh-TW" &&
                         length(getName(cols[j][i])) < 6) ? "\t\t " :
                        cols[j][i] == "ht" ? " " :
                        "\t "
                    tt = length(cols[j][i]) == 3 ? " │" :
                        (cols[j][i] != "zh-CN" && cols[j][i] != "zh-TW") ? "  │" : ""
                    name = getName(cols[j][i])
                    if (cols[j][i] == "zh-CN" ||
                        cols[j][i] == "zh-TW")
                        name = substr(name, 1, 12) "."
                    r = r name t "- " ansi("bold", cols[j][i]) tt " "
                } else
                    r = r "\t\t       │"
            }
            r = r RS
        }
        r = r "└" replicate("─", 22) "┴" replicate("─", 23) "┴" replicate("─", 23) "┘"
    }
    return r
}

# Return detailed information of languages as a string.
function getList(codes,    code, i, r, saveSortedIn) {
    r = NULLSTR
    if (!isarray(codes))
        r = getDetails(codes)
    else if (anything(codes)) {
        saveSortedIn = PROCINFO["sorted_in"]
        PROCINFO["sorted_in"] = "@ind_num_asc"
        for (i in codes)
            r = (r ? r RS prettify("target-seperator", replicate(Option["chr-target-seperator"], Option["width"])) RS \
                 : r) getDetails(codes[i])
        PROCINFO["sorted_in"] = saveSortedIn
    } else
        r = getDetails(Option["hl"])
    return r
}

####################################################################
# Help.awk                                                         #
####################################################################

# Return version as a string.
function getVersion(    build, gitHead, platform) {
    initAudioPlayer()
    initPager()
    platform = detectProgram("uname", "-o", 1)
    if (ENVIRON["TRANS_BUILD"])
        build = "-" ENVIRON["TRANS_BUILD"]
    else {
        gitHead = getGitHead()
        build = gitHead ? "-git:" gitHead : ""
    }

    return sprintf(ansi("bold", "%-22s%s%s") "\n\n", Name, Version, build) \
        sprintf("%-22s%s\n", "platform", platform)                      \
        sprintf("%-22s%s\n", "gawk (GNU Awk)", PROCINFO["version"])     \
        sprintf("%s\n", FriBidi ? FriBidi :
                "fribidi (GNU FriBidi) [NOT INSTALLED]")                \
        sprintf("%-22s%s\n", "audio player", AudioPlayer ? AudioPlayer :
                "[NOT INSTALLED]")                                      \
        sprintf("%-22s%s\n", "terminal pager", Pager ? Pager :
                "[NOT INSTALLED]")                                      \
        sprintf("%-22s%s\n", "terminal type", ENVIRON["TERM"])          \
        sprintf("%-22s%s (%s)\n", "user locale", UserLocale, getName(UserLang)) \
        sprintf("%-22s%s\n", "home language", Option["hl"])             \
        sprintf("%-22s%s\n", "source language", Option["sl"])           \
        sprintf("%-22s%s\n", "target language", join(Option["tl"], "+")) \
        sprintf("%-22s%s\n", "theme", Option["theme"])                  \
        sprintf("%-22s%s\n", "init file", InitScript ? InitScript : "[NONE]") \
        sprintf("\n%-22s%s", "Report bugs to:", "https://github.com/soimort/translate-shell/issues")
}

# Return help message as a string.
function getHelp() {
    return "Usage:  " ansi("bold", Command)                             \
        " [" ansi("underline", "OPTIONS") "]"                           \
        " [" ansi("underline", "SOURCE") "]"                            \
        ":[" ansi("underline", "TARGETS") "]"                           \
        " [" ansi("underline", "TEXT") "]..." RS                        \
        RS "Information options:" RS                                    \
        ins(1, ansi("bold", "-V") ", " ansi("bold", "-version")) RS     \
        ins(2, "Print version and exit.") RS                            \
        ins(1, ansi("bold", "-H") ", " ansi("bold", "-help")) RS        \
        ins(2, "Print help message and exit.") RS                       \
        ins(1, ansi("bold", "-M") ", " ansi("bold", "-man")) RS         \
        ins(2, "Show man page and exit.") RS                            \
        ins(1, ansi("bold", "-T") ", " ansi("bold", "-reference")) RS   \
        ins(2, "Print reference table of languages and exit.") RS       \
        ins(1, ansi("bold", "-R") ", " ansi("bold", "-reference-english")) RS \
        ins(2, "Print reference table of languages (in English names) and exit.") RS \
        ins(1, ansi("bold", "-L ") ansi("underline", "CODES")           \
            ", " ansi("bold", "-list ") ansi("underline", "CODES")) RS  \
        ins(2, "Print details of languages and exit.") RS               \
        ins(1, ansi("bold", "-U") ", " ansi("bold", "-upgrade")) RS     \
        ins(2, "Upgrade this program to latest version.") RS            \
        RS "Display options:" RS                                        \
        ins(1, ansi("bold", "-verbose")) RS                             \
        ins(2, "Verbose mode. (default)") RS                            \
        ins(1, ansi("bold", "-b") ", " ansi("bold", "-brief")) RS       \
        ins(2, "Brief mode.") RS                                        \
        ins(1, ansi("bold", "-d") ", " ansi("bold", "-dictionary")) RS  \
        ins(2, "Dictionary mode.") RS                                   \
        ins(1, ansi("bold", "-show-original ") ansi("underline", "Y/n")) RS \
        ins(2, "Show original text or not.") RS                         \
        ins(1, ansi("bold", "-show-original-phonetics ") ansi("underline", "Y/n")) RS \
        ins(2, "Show phonetic notation of original text or not.") RS    \
        ins(1, ansi("bold", "-show-translation ") ansi("underline", "Y/n")) RS \
        ins(2, "Show translation or not.") RS                           \
        ins(1, ansi("bold", "-show-translation-phonetics ") ansi("underline", "Y/n")) RS \
        ins(2, "Show phonetic notation of translation or not.") RS      \
        ins(1, ansi("bold", "-show-prompt-message ") ansi("underline", "Y/n")) RS \
        ins(2, "Show prompt message or not.") RS                        \
        ins(1, ansi("bold", "-show-languages ") ansi("underline", "Y/n")) RS \
        ins(2, "Show source and target languages or not.") RS           \
        ins(1, ansi("bold", "-show-original-dictionary ") ansi("underline", "y/N")) RS \
        ins(2, "Show dictionary entry of original text or not.") RS     \
        ins(1, ansi("bold", "-show-dictionary ") ansi("underline", "Y/n")) RS \
        ins(2, "Show dictionary entry of translation or not.") RS       \
        ins(1, ansi("bold", "-show-alternatives ") ansi("underline", "Y/n")) RS \
        ins(2, "Show alternative translations or not.") RS              \
        ins(1, ansi("bold", "-w ") ansi("underline", "NUM")             \
            ", " ansi("bold", "-width ") ansi("underline", "NUM")) RS   \
        ins(2, "Specify the screen width for padding.") RS              \
        ins(1, ansi("bold", "-indent ") ansi("underline", "NUM")) RS    \
        ins(2, "Specify the size of indent (number of spaces).") RS     \
        ins(1, ansi("bold", "-theme ") ansi("underline", "FILENAME")) RS \
        ins(2, "Specify the theme to use.") RS                          \
        ins(1, ansi("bold", "-no-theme")) RS                            \
        ins(2, "Do not use any other theme than default.") RS           \
        ins(1, ansi("bold", "-no-ansi")) RS                             \
        ins(2, "Do not use ANSI escape codes.") RS                      \
        RS "Audio options:" RS                                          \
        ins(1, ansi("bold", "-p, -play")) RS                            \
        ins(2, "Listen to the translation.") RS                         \
        ins(1, ansi("bold", "-player ") ansi("underline", "PROGRAM")) RS \
        ins(2, "Specify the audio player to use, and listen to the translation.") RS \
        ins(1, ansi("bold", "-no-play")) RS                             \
        ins(2, "Do not listen to the translation.") RS                  \
        RS "Terminal paging and browsing options:" RS                   \
        ins(1, ansi("bold", "-v") ", " ansi("bold", "-view")) RS        \
        ins(2, "View the translation in a terminal pager.") RS          \
        ins(1, ansi("bold", "-pager ") ansi("underline", "PROGRAM")) RS \
        ins(2, "Specify the terminal pager to use, and view the translation.") RS \
        ins(1, ansi("bold", "-no-view")) RS                             \
        ins(2, "Do not view the translation in a terminal pager.") RS   \
        ins(1, ansi("bold", "-browser ") ansi("underline", "PROGRAM")) RS \
        ins(2, "Specify the web browser to use.") RS                    \
        RS "Networking options:" RS                                     \
        ins(1, ansi("bold", "-x ") ansi("underline", "HOST:PORT")       \
            ", " ansi("bold", "-proxy ") ansi("underline", "HOST:PORT")) RS \
        ins(2, "Use HTTP proxy on given port.") RS                      \
        ins(1, ansi("bold", "-u ") ansi("underline", "STRING")          \
            ", " ansi("bold", "-user-agent ") ansi("underline", "STRING")) RS \
        ins(2, "Specify the User-Agent to identify as.") RS             \
        RS "Interactive shell options:" RS                              \
        ins(1, ansi("bold", "-I") ", " ansi("bold", "-interactive") ", " ansi("bold", "-shell")) RS \
        ins(2, "Start an interactive shell.") RS                        \
        ins(1, ansi("bold", "-E") ", " ansi("bold", "-emacs")) RS       \
        ins(2, "Start the GNU Emacs front-end for an interactive shell.") RS \
        ins(1, ansi("bold", "-no-rlwrap")) RS                           \
        ins(2, "Do not invoke rlwrap when starting an interactive shell.") RS \
        RS "I/O options:" RS                                            \
        ins(1, ansi("bold", "-i ") ansi("underline", "FILENAME")        \
            ", " ansi("bold", "-input ") ansi("underline", "FILENAME")) RS \
        ins(2, "Specify the input file.") RS                            \
        ins(1, ansi("bold", "-o ") ansi("underline", "FILENAME")        \
            ", " ansi("bold", "-output ") ansi("underline", "FILENAME")) RS \
        ins(2, "Specify the output file.") RS                           \
        RS "Language preference options:" RS                            \
        ins(1, ansi("bold", "-l ") ansi("underline", "CODE")            \
            ", " ansi("bold", "-lang ") ansi("underline", "CODE")) RS   \
        ins(2, "Specify your home language.") RS                        \
        ins(1, ansi("bold", "-s ") ansi("underline", "CODE")            \
            ", " ansi("bold", "-source ") ansi("underline", "CODE")) RS \
        ins(2, "Specify the source language.") RS                       \
        ins(1, ansi("bold", "-t ") ansi("underline", "CODES")           \
            ", " ansi("bold", "-target ") ansi("underline", "CODES")) RS \
        ins(2, "Specify the target language(s), joined by '+'.") RS     \
        RS "Other options:" RS                                          \
        ins(1, ansi("bold", "-no-init")) RS                             \
        ins(2, "Do not load any initialization script.") RS             \
        RS "See the man page " Command "(1) for more information."
}

# Show man page.
function showMan(    temp) {
    if (ENVIRON["TRANS_MANPAGE"]) {
        initPager()
        Groff = detectProgram("groff", "--version")
        if (Pager && Groff) {
            temp = "echo -E \"${TRANS_MANPAGE}\""
            temp = temp PIPE                                            \
                Groff " -Wall -mtty-char -mandoc -Tutf8 "               \
                "-rLL=" Option["width"] "n -rLT=" Option["width"] "n"
            switch (Pager) {
            case "less":
                temp = temp PIPE                                        \
                    Pager " -s -P\"\\ \\Manual page " Command "(1) line %lt (press h for help or q to quit)\""
                break
            case "most":
                temp = temp PIPE Pager " -Cs"
                break
            default: # more
                temp = temp PIPE Pager
            }
            system(temp)
            return
        }
    }
    if (fileExists("man/" Command ".1"))
        system("man man/" Command ".1" SUPERR)
    else if (system("man " Command SUPERR))
        print getHelp()
}

# Return a reference table of languages as a string.
# Parameters:
#     displayName = "endonym" or "name"
function getReference(displayName) {
    if (displayName == "name")
        return "┌─────────────────────────────┬──────────────────────┬─────────────────┐" RS \
            "│ " getName("af") "           - " ansi("bold", "af") "    │ " \
            getName("ha") "          - " ansi("bold", "ha") "  │ "      \
            getName("fa") "    - " ansi("bold", "fa") " │" RS           \
            "│ " getName("sq") "            - " ansi("bold", "sq") "    │ " \
            getName("he") "         - " ansi("bold", "he") "  │ "       \
            getName("pl") "     - " ansi("bold", "pl") " │" RS          \
            "│ " getName("ar") "              - " ansi("bold", "ar") "    │ " \
            getName("hi") "          - " ansi("bold", "hi") "  │ "      \
            getName("pt") " - " ansi("bold", "pt") " │" RS              \
            "│ " getName("hy") "            - " ansi("bold", "hy") "    │ " \
            getName("hmn") "          - " ansi("bold", "hmn") " │ "     \
            getName("pa") "    - " ansi("bold", "pa") " │" RS           \
            "│ " getName("az") "         - " ansi("bold", "az") "    │ " \
            getName("hu") "      - " ansi("bold", "hu") "  │ "          \
            getName("ro") "   - " ansi("bold", "ro") " │" RS            \
            "│ " getName("eu") "              - " ansi("bold", "eu") "    │ " \
            getName("is") "      - " ansi("bold", "is") "  │ "          \
            getName("ru") "    - " ansi("bold", "ru") " │" RS           \
            "│ " getName("be") "          - " ansi("bold", "be") "    │ " \
            getName("ig") "           - " ansi("bold", "ig") "  │ "     \
            getName("sr") "    - " ansi("bold", "sr") " │" RS           \
            "│ " getName("bn") "             - " ansi("bold", "bn") "    │ " \
            getName("id") "     - " ansi("bold", "id") "  │ "           \
            getName("st") "    - " ansi("bold", "st") " │" RS           \
            "│ " getName("bs") "             - " ansi("bold", "bs") "    │ " \
            getName("ga") "          - " ansi("bold", "ga") "  │ "      \
            getName("si") "    - " ansi("bold", "si") " │" RS           \
            "│ " getName("bg") "           - " ansi("bold", "bg") "    │ " \
            getName("it") "        - " ansi("bold", "it") "  │ "        \
            getName("sk") "     - " ansi("bold", "sk") " │" RS          \
            "│ " getName("ca") "             - " ansi("bold", "ca") "    │ " \
            getName("ja") "       - " ansi("bold", "ja") "  │ "         \
            getName("sl") "  - " ansi("bold", "sl") " │" RS             \
            "│ " getName("ceb") "             - " ansi("bold", "ceb") "   │ " \
            getName("jv") "       - " ansi("bold", "jv") "  │ "         \
            getName("so") "     - " ansi("bold", "so") " │" RS          \
            "│ " getName("ny") "            - " ansi("bold", "ny") "    │ " \
            getName("kn") "        - " ansi("bold", "kn") "  │ "        \
            getName("es") "    - " ansi("bold", "es") " │" RS           \
            "│ " getName("zh-CN") "  - " ansi("bold", "zh-CN") " │ "    \
            getName("kk") "         - " ansi("bold", "kk") "  │ "       \
            getName("su") "  - " ansi("bold", "su") " │" RS             \
            "│ " getName("zh-TW") " - " ansi("bold", "zh-TW") " │ "     \
            getName("km") "          - " ansi("bold", "km") "  │ "      \
            getName("sw") "    - " ansi("bold", "sw") " │" RS           \
            "│ " getName("hr") "            - " ansi("bold", "hr") "    │ " \
            getName("ko") "         - " ansi("bold", "ko") "  │ "       \
            getName("sv") "    - " ansi("bold", "sv") " │" RS           \
            "│ " getName("cs") "               - " ansi("bold", "cs") "    │ " \
            getName("lo") "            - " ansi("bold", "lo") "  │ "    \
            getName("tg") "      - " ansi("bold", "tg") " │" RS         \
            "│ " getName("da") "              - " ansi("bold", "da") "    │ " \
            getName("la") "          - " ansi("bold", "la") "  │ "      \
            getName("ta") "      - " ansi("bold", "ta") " │" RS         \
            "│ " getName("nl") "               - " ansi("bold", "nl") "    │ " \
            getName("lv") "        - " ansi("bold", "lv") "  │ "        \
            getName("te") "     - " ansi("bold", "te") " │" RS          \
            "│ " getName("en") "             - " ansi("bold", "en") "    │ " \
            getName("lt") "     - " ansi("bold", "lt") "  │ "           \
            getName("th") "       - " ansi("bold", "th") " │" RS        \
            "│ " getName("eo") "           - " ansi("bold", "eo") "    │ " \
            getName("mk") "     - " ansi("bold", "mk") "  │ "           \
            getName("tr") "    - " ansi("bold", "tr") " │" RS           \
            "│ " getName("et") "            - " ansi("bold", "et") "    │ " \
            getName("mg") "       - " ansi("bold", "mg") "  │ "         \
            getName("uk") "  - " ansi("bold", "uk") " │" RS             \
            "│ " getName("tl") "            - " ansi("bold", "tl") "    │ " \
            getName("ms") "          - " ansi("bold", "ms") "  │ "      \
            getName("ur") "       - " ansi("bold", "ur") " │" RS        \
            "│ " getName("fi") "             - " ansi("bold", "fi") "    │ " \
            getName("ml") "      - " ansi("bold", "ml") "  │ "          \
            getName("uz") "      - " ansi("bold", "uz") " │" RS         \
            "│ " getName("fr") "              - " ansi("bold", "fr") "    │ " \
            getName("mt") "        - " ansi("bold", "mt") "  │ "        \
            getName("vi") " - " ansi("bold", "vi") " │" RS              \
            "│ " getName("gl") "            - " ansi("bold", "gl") "    │ " \
            getName("mi") "          - " ansi("bold", "mi") "  │ "      \
            getName("cy") "      - " ansi("bold", "cy") " │" RS         \
            "│ " getName("ka") "            - " ansi("bold", "ka") "    │ " \
            getName("mr") "        - " ansi("bold", "mr") "  │ "        \
            getName("yi") "    - " ansi("bold", "yi") " │" RS           \
            "│ " getName("de") "              - " ansi("bold", "de") "    │ " \
            getName("mn") "      - " ansi("bold", "mn") "  │ "          \
            getName("yo") "     - " ansi("bold", "yo") " │" RS          \
            "│ " getName("el") "               - " ansi("bold", "el") "    │ " \
            getName("my") "        - " ansi("bold", "my") "  │ "        \
            getName("zu") "       - " ansi("bold", "zu") " │" RS        \
            "│ " getName("gu") "            - " ansi("bold", "gu") "    │ " \
            getName("ne") "         - " ansi("bold", "ne") "  │ "       \
            "                │" RS                                      \
            "│ " getName("ht") "      - " ansi("bold", "ht") "    │ "   \
            getName("no") "      - " ansi("bold", "no") "  │ "          \
            "                │" RS                                      \
            "└─────────────────────────────┴──────────────────────┴─────────────────┘"
    else
        return "┌──────────────────────┬───────────────────────┬─────────────────────┐" RS \
            "│ " getDisplay("af") "      - " ansi("bold", "af") "  │ "  \
            getDisplay("hu") "           - " ansi("bold", "hu") " │ "   \
            getDisplay("pl") "      - " ansi("bold", "pl") "    │" RS   \
            "│ " getDisplay("ar") "        - " ansi("bold", "ar") "  │ " \
            getDisplay("hy") "          - " ansi("bold", "hy") " │ "    \
            getDisplay("pt") "   - " ansi("bold", "pt") "    │" RS      \
            "│ " getDisplay("az") "   - " ansi("bold", "az") "  │ "     \
            getDisplay("id") " - " ansi("bold", "id") " │ "             \
            getDisplay("ro") "      - " ansi("bold", "ro") "    │" RS   \
            "│ " getDisplay("be") "     - " ansi("bold", "be") "  │ "   \
            getDisplay("ig") "             - " ansi("bold", "ig") " │ " \
            getDisplay("ru") "     - " ansi("bold", "ru") "    │" RS    \
            "│ " getDisplay("bg") "      - " ansi("bold", "bg") "  │ "  \
            getDisplay("is") "         - " ansi("bold", "is") " │ "     \
            getDisplay("si") "        - " ansi("bold", "si") "    │" RS \
            "│ " getDisplay("bn") "          - " ansi("bold", "bn") "  │ " \
            getDisplay("it") "         - " ansi("bold", "it") " │ "     \
            getDisplay("sk") "  - " ansi("bold", "sk") "    │" RS       \
            "│ " getDisplay("bs") "       - " ansi("bold", "bs") "  │ " \
            getDisplay("ja") "           - " ansi("bold", "ja") " │ "   \
            getDisplay("sl") " - " ansi("bold", "sl") "    │" RS        \
            "│ " getDisplay("ca") "         - " ansi("bold", "ca") "  │ " \
            getDisplay("jv") "        - " ansi("bold", "jv") " │ "      \
            getDisplay("so") "    - " ansi("bold", "so") "    │" RS     \
            "│ " getDisplay("ceb") "        - " ansi("bold", "ceb") " │ " \
            getDisplay("ka") "          - " ansi("bold", "ka") " │ "    \
            getDisplay("sq") "       - " ansi("bold", "sq") "    │" RS  \
            "│ " getDisplay("cs") "        - " ansi("bold", "cs") "  │ " \
            getDisplay("kk") "       - " ansi("bold", "kk") " │ "       \
            getDisplay("sr") "      - " ansi("bold", "sr") "    │" RS   \
            "│ " getDisplay("cy") "        - " ansi("bold", "cy") "  │ " \
            getDisplay("km") "         - " ansi("bold", "km") " │ "     \
            getDisplay("st") "     - " ansi("bold", "st") "    │" RS    \
            "│ " getDisplay("da") "          - " ansi("bold", "da") "  │ " \
            getDisplay("kn") "             - " ansi("bold", "kn") " │ " \
            getDisplay("su") "  - " ansi("bold", "su") "    │" RS       \
            "│ " getDisplay("de") "        - " ansi("bold", "de") "  │ " \
            getDisplay("ko") "           - " ansi("bold", "ko") " │ "   \
            getDisplay("sv") "     - " ansi("bold", "sv") "    │" RS    \
            "│ " getDisplay("el") "       - " ansi("bold", "el") "  │ " \
            getDisplay("la") "           - " ansi("bold", "la") " │ "   \
            getDisplay("sw") "   - " ansi("bold", "sw") "    │" RS      \
            "│ " getDisplay("en") "        - " ansi("bold", "en") "  │ " \
            getDisplay("lo") "              - " ansi("bold", "lo") " │ " \
            getDisplay("ta") "        - " ansi("bold", "ta") "    │" RS \
            "│ " getDisplay("eo") "      - " ansi("bold", "eo") "  │ "  \
            getDisplay("lt") "         - " ansi("bold", "lt") " │ "     \
            getDisplay("te") "       - " ansi("bold", "te") "    │" RS  \
            "│ " getDisplay("es") "        - " ansi("bold", "es") "  │ " \
            getDisplay("lv") "         - " ansi("bold", "lv") " │ "     \
            getDisplay("tg") "      - " ansi("bold", "tg") "    │" RS   \
            "│ " getDisplay("et") "          - " ansi("bold", "et") "  │ " \
            getDisplay("mg") "         - " ansi("bold", "mg") " │ "     \
            getDisplay("th") "         - " ansi("bold", "th") "    │" RS \
            "│ " getDisplay("eu") "        - " ansi("bold", "eu") "  │ " \
            getDisplay("mi") "            - " ansi("bold", "mi") " │ "  \
            getDisplay("tl") "     - " ansi("bold", "tl") "    │" RS    \
            "│ " getDisplay("fa") "          - " ansi("bold", "fa") "  │ " \
            getDisplay("mk") "       - " ansi("bold", "mk") " │ "       \
            getDisplay("tr") "      - " ansi("bold", "tr") "    │" RS   \
            "│ " getDisplay("fi") "          - " ansi("bold", "fi") "  │ " \
            getDisplay("ml") "           - " ansi("bold", "ml") " │ "   \
            getDisplay("uk") "  - " ansi("bold", "uk") "    │" RS       \
            "│ " getDisplay("fr") "       - " ansi("bold", "fr") "  │ " \
            getDisplay("mn") "           - " ansi("bold", "mn") " │ "   \
            getDisplay("ur") "        - " ansi("bold", "ur") "    │" RS \
            "│ " getDisplay("ga") "        - " ansi("bold", "ga") "  │ " \
            getDisplay("mr") "            - " ansi("bold", "mr") " │ "  \
            getDisplay("uz") " - " ansi("bold", "uz") "    │" RS        \
            "│ " getDisplay("gl") "         - " ansi("bold", "gl") "  │ " \
            getDisplay("ms") "    - " ansi("bold", "ms") " │ "          \
            getDisplay("vi") "  - " ansi("bold", "vi") "    │" RS       \
            "│ " getDisplay("gu") "         - " ansi("bold", "gu") "  │ " \
            getDisplay("mt") "            - " ansi("bold", "mt") " │ "  \
            getDisplay("yi") "       - " ansi("bold", "yi") "    │" RS  \
            "│ " getDisplay("ha") "          - " ansi("bold", "ha") "  │ " \
            getDisplay("my") "          - " ansi("bold", "my") " │ "    \
            getDisplay("yo") "      - " ansi("bold", "yo") "    │" RS   \
            "│ " getDisplay("he") "          - " ansi("bold", "he") "  │ " \
            getDisplay("ne") "            - " ansi("bold", "ne") " │ "  \
            getDisplay("zh-CN") "    - " ansi("bold", "zh-CN") " │" RS  \
            "│ " getDisplay("hi") "          - " ansi("bold", "hi") "  │ " \
            getDisplay("nl") "       - " ansi("bold", "nl") " │ "       \
            getDisplay("zh-TW") "    - " ansi("bold", "zh-TW") " │" RS  \
            "│ " getDisplay("hmn") "          - " ansi("bold", "hmn") " │ " \
            getDisplay("no") "            - " ansi("bold", "no") " │ "  \
            getDisplay("zu") "     - " ansi("bold", "zu") "    │" RS    \
            "│ " getDisplay("hr") "       - " ansi("bold", "hr") "  │ " \
            getDisplay("ny") "           - " ansi("bold", "ny") " │ "   \
            "                    │" RS                                  \
            "│ " getDisplay("ht") " - " ansi("bold", "ht") "  │ "       \
            getDisplay("pa") "            - " ansi("bold", "pa") " │ "  \
            "                    │" RS                                  \
            "└──────────────────────┴───────────────────────┴─────────────────────┘"
}

# Return detailed information of languages as a string.
function getList(codes,    code, i, r, saveSortedIn) {
    r = NULLSTR
    if (!isarray(codes))
        r = getDetails(codes)
    else if (anything(codes)) {
        saveSortedIn = PROCINFO["sorted_in"]
        PROCINFO["sorted_in"] = "@ind_num_asc"
        for (i in codes)
            r = (r ? r RS prettify("target-seperator", replicate(Option["chr-target-seperator"], Option["width"])) RS \
                 : r) getDetails(codes[i])
        PROCINFO["sorted_in"] = saveSortedIn
    } else
        r = getDetails(Option["hl"])
    return r
}