delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2015/07/27/11:58:40

X-Recipient: archive-cygwin AT delorie DOT com
DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:message-id:in-reply-to:references:date:subject
:from:to:mime-version:content-type; q=dns; s=default; b=iEH8oGiZ
ZiipUwrOG9ALBsDQuU4C04qYwurH0BRTlaCXoRqpQWDtE+lbHW8NerRik51G/FGt
A4GhlBZ76Pz5EndahCvzcakvHqPhCnEAjgXIq7wmIRijImFb1p9EtRrnXdtUTkyo
OkqEnrJ0N202pQqeV6qERwJ6PuOQgUfhD9c=
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:message-id:in-reply-to:references:date:subject
:from:to:mime-version:content-type; s=default; bh=W0NAsrLyUDTBin
knBL525k2/8fA=; b=CdNLMn22IRzwAUqIqU4z36Uev/Ce5QQ7ybkylNv7ms1uDz
X3kN5T/NuuopRZqh2V4bL01AqaFsx9JnM9wofpswsygNMi8MNHxPntgnuck8z0tZ
a0zgDnxEbUR1Kz3hzbwOVy1WSI74EU81LqQzQZYyaWaOWsHOzW8ctPTj7JCJs=
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Authentication-Results: sourceware.org; auth=none
X-Virus-Found: No
X-Spam-SWARE-Status: No, score=0.0 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2
X-HELO: lb3-smtp-cloud6.xs4all.net
Message-ID: <20bcab2c7a6ca2aa1990f8a421b674ae.squirrel@oude-webmail.xs4all.nl>
In-Reply-To: <994a85838723f326327975650e214a79.squirrel@oude-webmail.xs4all.nl>
References: <announce DOT 55B1677D DOT 5080303 AT towo DOT net> <63a08c60771faffa23bc1c029235301d DOT squirrel AT oude-webmail DOT xs4all DOT nl> <55B22422 DOT 6000601 AT towo DOT net> <d9ef810e0ad325a9b51f641a10a06f0b DOT squirrel AT oude-webmail DOT xs4all DOT nl> <55B2B644 DOT 8010506 AT towo DOT net> <be0351be5e3aa7b7ba980fc25f9cce0c DOT squirrel AT oude-webmail DOT xs4all DOT nl> <e731c3536912df8739a630e17ab5d8ec DOT squirrel AT oude-webmail DOT xs4all DOT nl> <10d3a46960f8ec71784bdf15a0ee6b58 DOT squirrel AT oude-webmail DOT xs4all DOT nl> <1e17310bb0689632cd19fd7648bd9907 DOT squirrel AT oude-webmail DOT xs4all DOT nl> <55B5109A DOT 4010700 AT towo DOT net> <4afa07869c07cd6a57441b221ca5fdf7 DOT squirrel AT oude-webmail DOT xs4all DOT nl> <994a85838723f326327975650e214a79 DOT squirrel AT oude-webmail DOT xs4all DOT nl>
Date: Mon, 27 Jul 2015 17:58:07 +0200
Subject: Re: [ANNOUNCEMENT] Update: mintty 2.1.2
From: "Houder" <houder AT xs4all DOT nl>
To: cygwin AT cygwin DOT com
User-Agent: SquirrelMail/1.4.22
MIME-Version: 1.0
X-IsSubscribed: yes

------=_20150727175807_31619
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 8bit

Hi Thomas,

Moving load_dwm_funcs() did the trick ...

Tested on 32-bits and 64-bits, W7

See appendix (winmain.c)

Henri
------=_20150727175807_31619
Content-Type: text/x-c; name="winmain.c"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="winmain.c"

// win.c (part of mintty)
// Copyright 2008-13 Andy Koppe
// Based on code from PuTTY-0.60 by Simon Tatham and team.
// Licensed under the terms of the GNU General Public License v3 or later.

#include "winpriv.h"

#include "term.h"
#include "appinfo.h"
#include "child.h"
#include "charset.h"

#include <locale.h>
#include <getopt.h>
#include <pwd.h>
#include <shellapi.h>

#include <sys/cygwin.h>

HINSTANCE inst;
HWND wnd;
HIMC imc;

bool win_is_full_screen;

static char **main_argv;
static int main_argc;
static ATOM class_atom;

static int extra_width, extra_height;
static bool fullscr_on_max;
static bool resizing;
static bool title_settable = true;
static bool daemonize = false;
static string border_style = 0;

static HBITMAP caretbm;

#if WINVER < 0x600

typedef struct {
  int cxLeftWidth;
  int cxRightWidth;
  int cyTopHeight;
  int cyBottomHeight;
} MARGINS;

#endif

static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
static HRESULT (WINAPI *pDwmExtendFrameIntoClientArea)(HWND, const MARGINS *);

// Helper for loading a system library. Using LoadLibrary() directly is insecure
// because Windows might be searching the current working directory first.
static HMODULE
load_sys_library(string name)
{
  char path[MAX_PATH];
  uint len = GetSystemDirectory(path, MAX_PATH);
  if (len && len + strlen(name) + 1 < MAX_PATH) {
    path[len] = '\\';
    strcpy(&path[len + 1], name);
    return LoadLibrary(path);
  }
  else
    return 0;
}

static void
load_dwm_funcs(void)
{
  HMODULE dwm = load_sys_library("dwmapi.dll");
  if (dwm) {
    pDwmIsCompositionEnabled =
      (void *)GetProcAddress(dwm, "DwmIsCompositionEnabled");
    pDwmExtendFrameIntoClientArea =
      (void *)GetProcAddress(dwm, "DwmExtendFrameIntoClientArea");
  }
}

void
win_set_timer(void (*cb)(void), uint ticks)
{ SetTimer(wnd, (UINT_PTR)cb, ticks, null); }

void
win_set_title(char *title)
{
  if (title_settable) {
    wchar wtitle[strlen(title) + 1];
    if (cs_mbstowcs(wtitle, title, lengthof(wtitle)) >= 0)
      SetWindowTextW(wnd, wtitle);
  }
}

void
win_copy_title(void)
{
  int len = GetWindowTextLengthW(wnd);
  wchar title[len + 1];
  len = GetWindowTextW(wnd, title, len + 1);
  win_copy(title, 0, len + 1);
}

void
win_prefix_title(const char * prefix)
{
  int len = GetWindowTextLengthW(wnd);
  wchar ptitle[strlen(prefix) + len + 1];
  int plen = cs_mbstowcs(ptitle, prefix, lengthof(ptitle));
  wchar * title = & ptitle[plen];
  len = GetWindowTextW(wnd, title, len + 1);
  SetWindowTextW(wnd, ptitle);
}

/*
 * Title stack (implemented as fixed-size circular buffer)
 */
static wstring titles[16];
static uint titles_i;

void
win_save_title(void)
{
  int len = GetWindowTextLengthW(wnd);
  wchar *title = newn(wchar, len + 1);
  GetWindowTextW(wnd, title, len + 1);
  delete(titles[titles_i]);
  titles[titles_i++] = title;
  if (titles_i == lengthof(titles))
    titles_i = 0;
}

void
win_restore_title(void)
{
  if (!titles_i)
    titles_i = lengthof(titles);
  wstring title = titles[--titles_i];
  if (title) {
    SetWindowTextW(wnd, title);
    delete(title);
    titles[titles_i] = 0;
  }
}

/*
 *  Switch to next or previous application window in z-order
 */

static HWND first_wnd, last_wnd;

static BOOL CALLBACK
wnd_enum_proc(HWND curr_wnd, LPARAM unused(lp)) {
  if (curr_wnd != wnd && !IsIconic(curr_wnd)) {
    WINDOWINFO curr_wnd_info;
    curr_wnd_info.cbSize = sizeof(WINDOWINFO);
    GetWindowInfo(curr_wnd, &curr_wnd_info);
    if (class_atom == curr_wnd_info.atomWindowType) {
      first_wnd = first_wnd ?: curr_wnd;
      last_wnd = curr_wnd;
    }
  }
  return true;
}

void
win_switch(bool back, bool alternate)
{
  first_wnd = 0, last_wnd = 0;
  EnumWindows(wnd_enum_proc, 0);
  if (first_wnd) {
    if (back)
      first_wnd = last_wnd;
    else
      SetWindowPos(wnd, last_wnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
                       | (alternate ? SWP_NOZORDER : SWP_NOREPOSITION));
    BringWindowToTop(first_wnd);
  }
}

static void
get_monitor_info(MONITORINFO *mip)
{
  HMONITOR mon = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
  mip->cbSize = sizeof(MONITORINFO);
  GetMonitorInfo(mon, mip);
}

/*
 * Minimise or restore the window in response to a server-side
 * request.
 */
void
win_set_iconic(bool iconic)
{
  if (iconic ^ IsIconic(wnd))
    ShowWindow(wnd, iconic ? SW_MINIMIZE : SW_RESTORE);
}

/*
 * Move the window in response to a server-side request.
 */
void
win_set_pos(int x, int y)
{
  trace_resize(("--- win_set_pos %d %d\n", x, y));
  if (!IsZoomed(wnd))
    SetWindowPos(wnd, null, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}

/*
 * Move the window to the top or bottom of the z-order in response
 * to a server-side request.
 */
void
win_set_zorder(bool top)
{
  SetWindowPos(wnd, top ? HWND_TOP : HWND_BOTTOM, 0, 0, 0, 0,
               SWP_NOMOVE | SWP_NOSIZE);
}

bool
win_is_iconic(void)
{
  return IsIconic(wnd);
}

void
win_get_pos(int *xp, int *yp)
{
  RECT r;
  GetWindowRect(wnd, &r);
  *xp = r.left;
  *yp = r.top;
}

void
win_get_pixels(int *height_p, int *width_p)
{
  RECT r;
  GetWindowRect(wnd, &r);
  *height_p = r.bottom - r.top;
  *width_p = r.right - r.left;
}

void
win_get_screen_chars(int *rows_p, int *cols_p)
{
  MONITORINFO mi;
  get_monitor_info(&mi);
  RECT fr = mi.rcMonitor;
  *rows_p = (fr.bottom - fr.top) / font_height;
  *cols_p = (fr.right - fr.left) / font_width;
}

void
win_set_pixels(int height, int width)
{
  trace_resize(("--- win_set_pixels %d %d\n", height, width));
  SetWindowPos(wnd, null, 0, 0,
               width + 2 * PADDING + extra_width,
               height + 2 * PADDING + extra_height,
               SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER);
}

static void
win_fix_position(void)
{
    RECT wr;
    GetWindowRect(wnd, &wr);
    MONITORINFO mi;
    get_monitor_info(&mi);
    RECT ar = mi.rcWork;

    // Correct edges. Top and left win if the window is too big.
    wr.left -= max(0, wr.right - ar.right);
    wr.top -= max(0, wr.bottom - ar.bottom);
    wr.left = max(wr.left, ar.left);
    wr.top = max(wr.top, ar.top);

    SetWindowPos(wnd, 0, wr.left, wr.top, 0, 0,
                 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}

void
win_set_chars(int rows, int cols)
{
  trace_resize(("--- win_set_chars %d×%d\n", rows, cols));
  win_set_pixels(rows * font_height, cols * font_width);
  win_fix_position();
}


// Clockwork
int get_tick_count(void) { return GetTickCount(); }
int cursor_blink_ticks(void) { return GetCaretBlinkTime(); }

static void
flash_taskbar(bool enable)
{
  static bool enabled;
  if (enable != enabled) {
    FlashWindowEx(&(FLASHWINFO){
      .cbSize = sizeof(FLASHWINFO),
      .hwnd = wnd,
      .dwFlags = enable ? FLASHW_TRAY | FLASHW_TIMER : FLASHW_STOP,
      .uCount = 1,
      .dwTimeout = 0
    });
    enabled = enable;
  }
}

/*
 * Bell.
 */
void
win_bell(void)
{
  if (cfg.bell_sound || cfg.bell_type) {
    if (cfg.bell_freq)
      Beep(cfg.bell_freq, cfg.bell_len);
    else {
      // 0  MB_OK               Default Beep
      // 1  MB_ICONSTOP         Critical Stop
      // 2  MB_ICONQUESTION     Question
      // 3  MB_ICONEXCLAMATION  Exclamation
      // 4  MB_ICONASTERISK     Asterisk
      // ?  0xFFFFFFFF          Simple Beep
      MessageBeep((cfg.bell_type - 1) * 16);
    }
  }
  if (cfg.bell_taskbar && !term.has_focus)
    flash_taskbar(true);
}

void
win_invalidate_all(void)
{
  InvalidateRect(wnd, null, true);
}

void
win_adapt_term_size(bool sync_size_with_font, bool scale_font_with_size)
{
  trace_resize(("--- win_adapt_term_size full %d Zoomed %d\n", win_is_fullscreen, IsZoomed(wnd)));
  if (IsIconic(wnd))
    return;

  if (sync_size_with_font && !win_is_fullscreen) {
    win_set_chars(term.rows, term.cols);
    //win_fix_position();
    win_invalidate_all();
    return;
  }

 /* Current window sizes ... */
  RECT cr, wr;
  GetClientRect(wnd, &cr);
  GetWindowRect(wnd, &wr);
  int client_width = cr.right - cr.left;
  int client_height = cr.bottom - cr.top;
  extra_width = wr.right - wr.left - client_width;
  extra_height = wr.bottom - wr.top - client_height;
  int term_width = client_width - 2 * PADDING;
  int term_height = client_height - 2 * PADDING;

  if (scale_font_with_size) {
    // calc preliminary size (without font scaling), as below
    // should use term_height rather than rows; calc and store in term_resize
    int cols0 = max(1, term_width / font_width);
    int rows0 = max(1, term_height / font_height);

    // rows0/term.rows gives a rough scaling factor for font_height
    // cols0/term.cols gives a rough scaling factor for font_width
    // font_height, font_width give a rough scaling indication for font_size
    // height or width could be considered more according to preference
    bool bigger = rows0 * cols0 > term.rows * term.cols;
    int font_size1 =
      // heuristic best approach taken...
      // bigger
      //   ? max(font_size * rows0 / term.rows, font_size * cols0 / term.cols)
      //   : min(font_size * rows0 / term.rows, font_size * cols0 / term.cols);
      // bigger
      //   ? font_size * rows0 / term.rows + 2
      //   : font_size * rows0 / term.rows;
      bigger
        ? (font_size * rows0 / term.rows + font_size * cols0 / term.cols) / 2 + 1
        : (font_size * rows0 / term.rows + font_size * cols0 / term.cols) / 2;
      // bigger
      //   ? font_size * rows0 * cols0 / (term.rows * term.cols)
      //   : font_size * rows0 * cols0 / (term.rows * term.cols);
      trace_resize(("term size %d %d -> %d %d\n", term.rows, term.cols, rows0, cols0));
      trace_resize(("font size %d -> %d\n", font_size, font_size1));

    if (font_size1 != font_size)
      win_set_font_size(font_size1, false);
  }

  int cols = max(1, term_width / font_width);
  int rows = max(1, term_height / font_height);
  if (rows != term.rows || cols != term.cols) {
    term_resize(rows, cols);
    struct winsize ws = {rows, cols, cols * font_width, rows * font_height};
    child_resize(&ws);
  }
  win_invalidate_all();
}

bool
win_is_glass_available(void)
{
  BOOL result = false;
  if (pDwmIsCompositionEnabled)
    pDwmIsCompositionEnabled(&result);
  return result;
}

static void
update_glass(void)
{
  if (pDwmExtendFrameIntoClientArea) {
    bool enabled =
      cfg.transparency == TR_GLASS && !win_is_fullscreen &&
      !(cfg.opaque_when_focused && term.has_focus);
    pDwmExtendFrameIntoClientArea(wnd, &(MARGINS){enabled ? -1 : 0, 0, 0, 0});
  }
}

/*
 * Go full-screen. This should only be called when we are already
 * maximised.
 */
static void
make_fullscreen(void)
{
  win_is_fullscreen = true;

 /* Remove the window furniture. */
  LONG style = GetWindowLong(wnd, GWL_STYLE);
  style &= ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME);
  SetWindowLong(wnd, GWL_STYLE, style);

 /* The glass effect doesn't work for fullscreen windows */
  update_glass();

 /* Resize ourselves to exactly cover the nearest monitor. */
  MONITORINFO mi;
  get_monitor_info(&mi);
  RECT fr = mi.rcMonitor;
  SetWindowPos(wnd, HWND_TOP, fr.left, fr.top,
               fr.right - fr.left, fr.bottom - fr.top, SWP_FRAMECHANGED);
}

/*
 * Clear the full-screen attributes.
 */
static void
clear_fullscreen(void)
{
  win_is_fullscreen = false;
  update_glass();

 /* Reinstate the window furniture. */
  LONG style = GetWindowLong(wnd, GWL_STYLE);
  if (border_style) {
    if (strcmp (border_style, "void") != 0) {
      style |= WS_THICKFRAME;
    }
  }
  else {
    style |= WS_CAPTION | WS_BORDER | WS_THICKFRAME;
  }
  SetWindowLong(wnd, GWL_STYLE, style);
  SetWindowPos(wnd, null, 0, 0, 0, 0,
               SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}

/*
 * Maximise or restore the window in response to a server-side request.
 * Argument value of 2 means go fullscreen.
 */
void
win_maximise(int max)
{
  if (max == -2) // toggle full screen
    max = win_is_fullscreen ? 0 : 2;
  if (IsZoomed(wnd)) {
    if (!max)
      ShowWindow(wnd, SW_RESTORE);
    else if (max == 2 && !win_is_fullscreen)
      make_fullscreen();
  }
  else if (max) {
    if (max == 2)
      fullscr_on_max = true;
    ShowWindow(wnd, SW_MAXIMIZE);
  }
}

/*
 * Go back to configured window size.
 */
static void
default_size(void)
{
  if (IsZoomed(wnd))
    ShowWindow(wnd, SW_RESTORE);
  win_set_chars(cfg.rows, cfg.cols);
}

static void
update_transparency(void)
{
  int trans = cfg.transparency;
  if (trans == TR_GLASS)
    trans = 0;
  LONG style = GetWindowLong(wnd, GWL_EXSTYLE);
  style = trans ? style | WS_EX_LAYERED : style & ~WS_EX_LAYERED;
  SetWindowLong(wnd, GWL_EXSTYLE, style);
  if (trans) {
    if (cfg.opaque_when_focused && term.has_focus)
      trans = 0;
    SetLayeredWindowAttributes(wnd, 0, 255 - (uchar)trans, LWA_ALPHA);
  }

  update_glass();
}

void
win_update_scrollbar(void)
{
  int scrollbar = term.show_scrollbar ? cfg.scrollbar : 0;
  LONG style = GetWindowLong(wnd, GWL_STYLE);
  SetWindowLong(wnd, GWL_STYLE,
                scrollbar ? style | WS_VSCROLL : style & ~WS_VSCROLL);
  LONG exstyle = GetWindowLong(wnd, GWL_EXSTYLE);
  SetWindowLong(wnd, GWL_EXSTYLE,
                scrollbar < 0 ? exstyle | WS_EX_LEFTSCROLLBAR
                              : exstyle & ~WS_EX_LEFTSCROLLBAR);
  SetWindowPos(wnd, null, 0, 0, 0, 0,
               SWP_NOACTIVATE | SWP_NOMOVE |
               SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}

void
win_reconfig(void)
{
  trace_resize(("--- win_reconfig\n"));
 /* Pass new config data to the terminal */
  term_reconfig();

  bool font_changed =
    strcmp(new_cfg.font.name, cfg.font.name) ||
    new_cfg.font.size != cfg.font.size ||
    new_cfg.font.isbold != cfg.font.isbold ||
    new_cfg.bold_as_font != cfg.bold_as_font ||
    new_cfg.bold_as_colour != cfg.bold_as_colour ||
    new_cfg.font_smoothing != cfg.font_smoothing;

  if (new_cfg.fg_colour != cfg.fg_colour)
    win_set_colour(FG_COLOUR_I, new_cfg.fg_colour);

  if (new_cfg.bg_colour != cfg.bg_colour)
    win_set_colour(BG_COLOUR_I, new_cfg.bg_colour);

  if (new_cfg.cursor_colour != cfg.cursor_colour)
    win_set_colour(CURSOR_COLOUR_I, new_cfg.cursor_colour);

  /* Copy the new config and refresh everything */
  copy_config(&cfg, &new_cfg);
  if (font_changed) {
    win_init_fonts(cfg.font.size);
    trace_resize((" (win_reconfig -> win_adapt_term_size)\n"));
    win_adapt_term_size(true, false);
  }
  win_update_scrollbar();
  update_transparency();
  win_update_mouse();

  bool old_ambig_wide = cs_ambig_wide;
  cs_reconfig();
  if (term.report_font_changed && font_changed)
    if (term.report_ambig_width)
      child_write(cs_ambig_wide ? "\e[2W" : "\e[1W", 4);
    else
      child_write("\e[0W", 4);
  else if (term.report_ambig_width && old_ambig_wide != cs_ambig_wide)
    child_write(cs_ambig_wide ? "\e[2W" : "\e[1W", 4);
}

static bool
confirm_exit(void)
{
  if (!child_is_parent())
    return true;

  /* retrieve list of child processes */
  char * pscmd = "procps -o pid,ruser=USER -o comm -t %s 2> /dev/null || ps -ef";
  char * tty = child_tty();
  if (strrchr (tty, '/'))
    tty = strrchr (tty, '/') + 1;
  char cmd[strlen(pscmd) + strlen(tty) + 1];
  sprintf (cmd, pscmd, tty, tty);
  FILE * procps = popen (cmd, "r");
  char * msg_pre = "Processes are running in session:\n";
  char * msg_post = "Close anyway?";
  char * msg = malloc (strlen (msg_pre) + 1);
  strcpy (msg, msg_pre);
  if (procps) {
    char line[999];  // use very long input despite narrow msg box
                     // to avoid high risk of clipping within UTF-8 
                     // and failing the wide character transformation
    bool first = true;
    bool filter_tty = false;
    while (fgets(line, sizeof line, procps)) {
      line[strcspn(line, "\r\n")] = 0;  /* trim newline */
      if (first || !filter_tty || strstr (line, tty))  // should check column position too...
      {
        if (first) {
          if (strstr (line, "TTY")) {
            filter_tty = true;
          }
          first = false;
        }
        msg = realloc (msg, strlen (msg) + strlen (line) + 2);
        strcat (msg, line);
        strcat (msg, "\n");
      }
    }
    fclose(procps);
  }
  msg = realloc (msg, strlen (msg) + strlen (msg_post) + 1);
  strcat (msg, msg_post);

  size_t size = cs_mbstowcs(0, msg, 0) + 1;
  int ret;
  if (size) {
    wchar msgw[size];
    cs_mbstowcs(msgw, msg, size);
    wchar appn[strlen(APPNAME) + 1];
    cs_mbstowcs(appn, APPNAME, sizeof appn);
    ret =
      MessageBoxW(
        wnd, msgw,
        appn, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2
      );
  }
  else {
    ret =
      MessageBox(
        wnd, msg,
        APPNAME, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2
      );
  }

  // Treat failure to show the dialog as confirmation.
  return !ret || ret == IDOK;
}

static LRESULT CALLBACK
win_proc(HWND wnd, UINT message, WPARAM wp, LPARAM lp)
{
  switch (message) {
    when WM_TIMER: {
      KillTimer(wnd, wp);
      void_fn cb = (void_fn)wp;
      cb();
      return 0;
    }
    when WM_CLOSE:
      if (!cfg.confirm_exit || confirm_exit())
        child_kill((GetKeyState(VK_SHIFT) & 0x80) != 0);
      return 0;
    when WM_COMMAND or WM_SYSCOMMAND:
      switch (wp & ~0xF) {  /* low 4 bits reserved to Windows */
        when IDM_OPEN: term_open();
        when IDM_COPY: term_copy();
        when IDM_PASTE: win_paste();
        when IDM_SELALL: term_select_all(); win_update();
        when IDM_RESET: term_reset(); win_update();
        when IDM_DEFSIZE: default_size();
        when IDM_FULLSCREEN: win_maximise(win_is_fullscreen ? 0 : 2);
        when IDM_FLIPSCREEN: term_flip_screen();
        when IDM_OPTIONS: win_open_config();
        when IDM_NEW: child_fork(main_argc, main_argv);
        when IDM_COPYTITLE: win_copy_title();
      }
    when WM_VSCROLL:
      switch (LOWORD(wp)) {
        when SB_BOTTOM:   term_scroll(-1, 0);
        when SB_TOP:      term_scroll(+1, 0);
        when SB_LINEDOWN: term_scroll(0, +1);
        when SB_LINEUP:   term_scroll(0, -1);
        when SB_PAGEDOWN: term_scroll(0, +max(1, term.rows - 1));
        when SB_PAGEUP:   term_scroll(0, -max(1, term.rows - 1));
        when SB_THUMBPOSITION or SB_THUMBTRACK: {
          SCROLLINFO info;
          info.cbSize = sizeof(SCROLLINFO);
          info.fMask = SIF_TRACKPOS;
          GetScrollInfo(wnd, SB_VERT, &info);
          term_scroll(1, info.nTrackPos);
        }
      }
    when WM_LBUTTONDOWN: win_mouse_click(MBT_LEFT, lp);
    when WM_RBUTTONDOWN: win_mouse_click(MBT_RIGHT, lp);
    when WM_MBUTTONDOWN: win_mouse_click(MBT_MIDDLE, lp);
    when WM_LBUTTONUP: win_mouse_release(MBT_LEFT, lp);
    when WM_RBUTTONUP: win_mouse_release(MBT_RIGHT, lp);
    when WM_MBUTTONUP: win_mouse_release(MBT_MIDDLE, lp);
    when WM_MOUSEMOVE: win_mouse_move(false, lp);
    when WM_NCMOUSEMOVE: win_mouse_move(true, lp);
    when WM_MOUSEWHEEL: win_mouse_wheel(wp, lp);
    when WM_KEYDOWN or WM_SYSKEYDOWN:
      if (win_key_down(wp, lp))
        return 0;
    when WM_KEYUP or WM_SYSKEYUP:
      if (win_key_up(wp, lp))
        return 0;
    when WM_CHAR or WM_SYSCHAR:
      child_sendw(&(wchar){wp}, 1);
      return 0;
    when WM_INPUTLANGCHANGE:
      win_set_ime_open(ImmIsIME(GetKeyboardLayout(0)) && ImmGetOpenStatus(imc));
    when WM_IME_NOTIFY:
      if (wp == IMN_SETOPENSTATUS)
        win_set_ime_open(ImmGetOpenStatus(imc));
    when WM_IME_STARTCOMPOSITION:
      ImmSetCompositionFont(imc, &lfont);
    when WM_IME_COMPOSITION:
      if (lp & GCS_RESULTSTR) {
        LONG len = ImmGetCompositionStringW(imc, GCS_RESULTSTR, null, 0);
        if (len > 0) {
          char buf[len];
          ImmGetCompositionStringW(imc, GCS_RESULTSTR, buf, len);
          child_sendw((wchar *)buf, len / 2);
        }
        return 1;
      }
    when WM_PAINT:
      win_paint();
      return 0;
    when WM_SETFOCUS:
      term_set_focus(true);
      CreateCaret(wnd, caretbm, 0, 0);
      flash_taskbar(false);  /* stop */
      win_update();
      update_transparency();
      ShowCaret(wnd);
    when WM_KILLFOCUS:
      win_show_mouse();
      term_set_focus(false);
      DestroyCaret();
      win_update();
      update_transparency();
    when WM_ENTERSIZEMOVE:
      trace_resize(("--- WM_ENTERSIZEMOVE VK_SHIFT %02X\n", GetKeyState(VK_SHIFT)));
      resizing = true;
    when WM_EXITSIZEMOVE or WM_CAPTURECHANGED:  // after mouse-drag resizing
      trace_resize(("--- WM_EXITSIZEMOVE (resizing %d) VK_SHIFT %02X\n", resizing, GetKeyState(VK_SHIFT)));
      if (resizing) {
        resizing = false;
        win_destroy_tip();
        trace_resize((" (win_proc -> win_adapt_term_size)\n"));
        win_adapt_term_size(GetKeyState(VK_SHIFT) & 0x80, false);
      }
    when WM_SIZING: {  // mouse-drag window resizing
      trace_resize(("--- WM_SIZING (resizing %d) VK_SHIFT %02X\n", resizing, GetKeyState(VK_SHIFT)));
     /*
      * This does two jobs:
      * 1) Keep the tip uptodate
      * 2) Make sure the window size is _stepped_ in units of the font size.
      */
      LPRECT r = (LPRECT) lp;
      int width = r->right - r->left - extra_width - 2 * PADDING;
      int height = r->bottom - r->top - extra_height - 2 * PADDING;
      int cols = max(1, (float)width / font_width + 0.5);
      int rows = max(1, (float)height / font_height + 0.5);

      int ew = width - cols * font_width;
      int eh = height - rows * font_height;

      if (wp >= WMSZ_BOTTOM) {
        wp -= WMSZ_BOTTOM;
        r->bottom -= eh;
      }
      else if (wp >= WMSZ_TOP) {
        wp -= WMSZ_TOP;
        r->top += eh;
      }

      if (wp == WMSZ_RIGHT)
        r->right -= ew;
      else if (wp == WMSZ_LEFT)
        r->left += ew;

      win_show_tip(r->left + extra_width, r->top + extra_height, cols, rows);

      return ew || eh;
    }
    when WM_SIZE: {
      trace_resize(("--- WM_SIZE (resizing %d) VK_SHIFT %02X\n", resizing, GetKeyState(VK_SHIFT)));
      if (wp == SIZE_RESTORED && win_is_fullscreen)
        clear_fullscreen();
      else if (wp == SIZE_MAXIMIZED && fullscr_on_max) {
        fullscr_on_max = false;
        make_fullscreen();
      }

      if (!resizing) {
        trace_resize((" (win_proc -> win_adapt_term_size)\n"));
        win_adapt_term_size(false, GetKeyState(VK_SHIFT) & 0x80);
      }

      return 0;
    }
    when WM_INITMENU:
      win_update_menus();
      return 0;
  }
 /*
  * Any messages we don't process completely above are passed through to
  * DefWindowProc() for default processing.
  */
  return DefWindowProcW(wnd, message, wp, lp);
}

static const char help[] =
  "Usage: " APPNAME " [OPTION]... [ PROGRAM [ARG]... | - ]\n"
  "\n"
  "Start a new terminal session running the specified program or the user's shell.\n"
  "If a dash is given instead of a program, invoke the shell as a login shell.\n"
  "\n"
  "Options:\n"
  "  -c, --config FILE     Load specified config file\n"
  "  -e, --exec            Treat remaining arguments as the command to execute\n"
  "  -h, --hold never|start|error|always  Keep window open after command finishes\n"
  "  -i, --icon FILE[,IX]  Load window icon from file, optionally with index\n"
  "  -l, --log FILE|-      Log output to file or stdout\n"
  "  -o, --option OPT=VAL  Override config file option with given value\n"
  "  -p, --position X,Y    Open window at specified coordinates\n"
  "  -s, --size COLS,ROWS  Set screen size in characters\n"
  "  -t, --title TITLE     Set window title (default: the invoked command)\n"
  "  -u, --utmp            Create a utmp entry\n"
  "  -w, --window normal|min|max|full|hide  Set initial window state\n"
  "      --class CLASS     Set window class name (default: " APPNAME ")\n"
  "  -H, --help            Display help and exit\n"
  "  -V, --version         Print version information and exit\n"
;

static const char short_opts[] = "+:c:eh:i:l:o:p:s:t:T:B:uw:HV:D";

static const struct option
opts[] = {
  {"config",   required_argument, 0, 'c'},
  {"exec",     no_argument,       0, 'e'},
  {"hold",     required_argument, 0, 'h'},
  {"icon",     required_argument, 0, 'i'},
  {"log",      required_argument, 0, 'l'},
  {"utmp",     no_argument,       0, 'u'},
  {"option",   required_argument, 0, 'o'},
  {"position", required_argument, 0, 'p'},
  {"size",     required_argument, 0, 's'},
  {"title",    required_argument, 0, 't'},
  {"Title",    required_argument, 0, 'T'},
  {"Border",   required_argument, 0, 'B'},
  {"window",   required_argument, 0, 'w'},
  {"class",    required_argument, 0, 'C'},
  {"help",     no_argument,       0, 'H'},
  {"version",  no_argument,       0, 'V'},
  {"daemon",   no_argument,       0, 'D'},
  {0, 0, 0, 0}
};

static void
show_msg(FILE *stream, string msg)
{
  if (fputs(msg, stream) < 0 || fflush(stream) < 0)
    MessageBox(0, msg, APPNAME, MB_OK);
}

static no_return __attribute__((format(printf, 1, 2)))
error(char *format, ...)
{
  char *msg;
  va_list va;
  va_start(va, format);
  vasprintf(&msg, format, va);
  va_end(va);
  msg = asform("%s: %s\nTry '--help' for more information.\n",
               main_argv[0], msg);
  show_msg(stderr, msg);
  exit(1);
}

static void __attribute__((format(printf, 1, 2)))
warn(char *format, ...)
{
  char *msg;
  va_list va;
  va_start(va, format);
  vasprintf(&msg, format, va);
  va_end(va);
  msg = asform("%s: %s\n", main_argv[0], msg);
  show_msg(stderr, msg);
}

int
main(int argc, char *argv[])
{
  main_argv = argv;
  main_argc = argc;
// Henri: too early!
#if 0
  load_dwm_funcs();
#endif
  init_config();
  cs_init();

  // Determine home directory.
  home = getenv("HOME");
#if CYGWIN_VERSION_DLL_MAJOR >= 1005
  // Before Cygwin 1.5, the passwd structure is faked.
  struct passwd *pw = getpwuid(getuid());
#endif
  home = home ? strdup(home) :
#if CYGWIN_VERSION_DLL_MAJOR >= 1005
    (pw && pw->pw_dir && *pw->pw_dir) ? strdup(pw->pw_dir) :
#endif
    asform("/home/%s", getlogin());

  // Set size and position defaults.
  STARTUPINFO sui;
  GetStartupInfo(&sui);
  cfg.window = sui.dwFlags & STARTF_USESHOWWINDOW ? sui.wShowWindow : SW_SHOW;
  cfg.x = cfg.y = CW_USEDEFAULT;

  load_config("/etc/minttyrc");
  string rc_file = asform("%s/.minttyrc", home);
  load_config(rc_file);
  delete(rc_file);

  if (getenv("MINTTY_ROWS")) {
    set_arg_option("Rows", getenv("MINTTY_ROWS"));
  }
  if (getenv("MINTTY_COLS")) {
    set_arg_option("Columns", getenv("MINTTY_COLS"));
  }

  for (;;) {
    int opt = getopt_long(argc, argv, short_opts, opts, 0);
    if (opt == -1 || opt == 'e')
      break;
    char *longopt = argv[optind - 1], *shortopt = (char[]){'-', optopt, 0};
    switch (opt) {
      when 'c': load_config(optarg);
      when 'h': set_arg_option("Hold", optarg);
      when 'i': set_arg_option("Icon", optarg);
      when 'l': set_arg_option("Log", optarg);
      when 'o': parse_arg_option(optarg);
      when 'p':
        if (sscanf(optarg, "%i,%i%1s", &cfg.x, &cfg.y, (char[2]){}) != 2)
          error("syntax error in position argument '%s'", optarg);
      when 's':
        if (sscanf(optarg, "%u,%u%1s", &cfg.cols, &cfg.rows, (char[2]){}) != 2)
          error("syntax error in size argument '%s'", optarg);
        remember_arg("Columns");
        remember_arg("Rows");
      when 't': set_arg_option("Title", optarg);
      when 'T':
        set_arg_option("Title", optarg);
        title_settable = false;
      when 'B':
        border_style = strdup (optarg);
      when 'u': cfg.utmp = true;
      when 'w': set_arg_option("Window", optarg);
      when 'C': set_arg_option("Class", optarg);
      when 'D':
        daemonize = true;
      when 'H':
        show_msg(stdout, help);
        return 0;
      when 'V':
        show_msg(stdout, VERSION_TEXT);
        return 0;
      when '?':
        error("unknown option '%s'", optopt ? shortopt : longopt);
      when ':':
        error("option '%s' requires an argument",
              longopt[1] == '-' ? longopt : shortopt);
    }
  }

  finish_config();

  // if started from console, try to detach from caller's terminal (~daemonize)
  // in order to not suppress signals
  // (indicated by isatty if linked with -mwindows)
#if 0 // Thomas
  if (daemonize && !isatty(0)) {
    if (fork() > 0) exit(0);
    setsid();
  }
#endif

#if 1 // Henri
if (getppid() != (pid_t)1) {
    if (getpgrp() == getpid()) {
        switch (fork()) {
        case -1:
            error("fork");
        case 0:
            /* child */
            break;
        default:
            /* parent */
            return 0;
        }
    }

    if (setsid() < 0) {
        error("setsid");
    }
} // if (getppid() != (pid_t)1)
#endif

// Henri: load dwmapi.dll when it makes sense (after fork())
#if 1
load_dwm_funcs();
#endif

  // Work out what to execute.
  argv += optind;
  if (*argv && (argv[1] || strcmp(*argv, "-")))
    cmd = *argv;
  else {
    // Look up the user's shell.
    cmd = getenv("SHELL");
    cmd = cmd ? strdup(cmd) :
#if CYGWIN_VERSION_DLL_MAJOR >= 1005
      (pw && pw->pw_shell && *pw->pw_shell) ? strdup(pw->pw_shell) :
#endif
      "/bin/sh";

    // Determine the program name argument.
    char *slash = strrchr(cmd, '/');
    char *arg0 = slash ? slash + 1 : cmd;

    // Prepend '-' if a login shell was requested.
    if (*argv)
      arg0 = asform("-%s", arg0);

    // Create new argument array.
    argv = newn(char *, 2);
    *argv = arg0;
  }

  // Load icon if specified.
  HICON large_icon = 0, small_icon = 0;
  if (*cfg.icon) {
    string icon_file = strdup(cfg.icon);
    uint icon_index = 0;
    char *comma = strrchr(icon_file, ',');
    if (comma) {
      char *start = comma + 1, *end;
      icon_index = strtoul(start, &end, 0);
      if (start != end && !*end)
        *comma = 0;
      else
        icon_index = 0;
    }
    SetLastError(0);
#if CYGWIN_VERSION_API_MINOR >= 181
    wchar *win_icon_file = cygwin_create_path(CCP_POSIX_TO_WIN_W, icon_file);
    if (win_icon_file) {
      ExtractIconExW(win_icon_file, icon_index, &large_icon, &small_icon, 1);
      free(win_icon_file);
    }
#else
    char win_icon_file[MAX_PATH];
    cygwin_conv_to_win32_path(icon_file, win_icon_file);
    ExtractIconExA(win_icon_file, icon_index, &large_icon, &small_icon, 1);
#endif
    if (!large_icon) {
      small_icon = 0;
      uint error = GetLastError();
      if (error) {
        char msg[1024];
        FormatMessage(
          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
          0, error, 0, msg, sizeof msg, 0
        );
        warn("could not load icon from '%s': %s", cfg.icon, msg);
      }
      else
        warn("could not load icon from '%s'", cfg.icon);
    }
    delete(icon_file);
  }

  // Set the AppID if specified and the required function is available.
  if (*cfg.app_id) {
    HMODULE shell = load_sys_library("shell32.dll");
    HRESULT (WINAPI *pSetAppID)(PCWSTR) =
      (void *)GetProcAddress(shell, "SetCurrentProcessExplicitAppUserModelID");

    if (pSetAppID) {
      size_t size = cs_mbstowcs(0, cfg.app_id, 0) + 1;
      if (size) {
        wchar buf[size];
        cs_mbstowcs(buf, cfg.app_id, size);
        pSetAppID(buf);
      }
    }
  }

  inst = GetModuleHandle(NULL);

  // Window class name.
  wstring wclass = _W(APPNAME);
  if (*cfg.class) {
    size_t size = cs_mbstowcs(0, cfg.class, 0) + 1;
    if (size) {
      wchar *buf = newn(wchar, size);
      cs_mbstowcs(buf, cfg.class, size);
      wclass = buf;
    }
    else
      fputs("Using default class name due to invalid characters.\n", stderr);
  }

  // Put child command line into window title if we haven't got one already.
  string title = cfg.title;
  if (!*title) {
    size_t len;
    char *argz;
    argz_create(argv, &argz, &len);
    argz_stringify(argz, len, ' ');
    title = argz;
  }

  // Convert title to Unicode. Default to application name if unsuccessful.
  wstring wtitle = _W(APPNAME);
  {
    size_t size = cs_mbstowcs(0, title, 0) + 1;
    if (size) {
      wchar *buf = newn(wchar, size);
      cs_mbstowcs(buf, title, size);
      wtitle = buf;
    }
    else
      fputs("Using default title due to invalid characters.\n", stderr);
  }

  // The window class.
  class_atom = RegisterClassExW(&(WNDCLASSEXW){
    .cbSize = sizeof(WNDCLASSEXW),
    .style = 0,
    .lpfnWndProc = win_proc,
    .cbClsExtra = 0,
    .cbWndExtra = 0,
    .hInstance = inst,
    .hIcon = large_icon ?: LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON)),
    .hIconSm = small_icon,
    .hCursor = LoadCursor(null, IDC_IBEAM),
    .hbrBackground = null,
    .lpszMenuName = null,
    .lpszClassName = wclass,
  });


  // Initialise the fonts, thus also determining their width and height.
  win_init_fonts(cfg.font.size);

  // Reconfigure the charset module now that arguments have been converted,
  // the locale/charset settings have been loaded, and the font width has
  // been determined.
  cs_reconfig();

  // Determine window sizes.
  int term_width = font_width * cfg.cols;
  int term_height = font_height * cfg.rows;

  RECT cr = {0, 0, term_width + 2 * PADDING, term_height + 2 * PADDING};
  RECT wr = cr;
  AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, false);
  int width = wr.right - wr.left;
  int height = wr.bottom - wr.top;

  if (cfg.scrollbar)
    width += GetSystemMetrics(SM_CXVSCROLL);

  extra_width = width - (cr.right - cr.left);
  extra_height = height - (cr.bottom - cr.top);

  // Having x == CW_USEDEFAULT but not still triggers the default positioning,
  // whereas y==CW_USEFAULT but not x results in an invisible window, so to
  // avoid the latter, require both x and y to be set for custom positioning.
  if (cfg.y == (int)CW_USEDEFAULT)
    cfg.x = CW_USEDEFAULT;

  // Create initial window.
  wnd = CreateWindowExW(cfg.scrollbar < 0 ? WS_EX_LEFTSCROLLBAR : 0,
                        wclass, wtitle,
                        WS_OVERLAPPEDWINDOW | (cfg.scrollbar ? WS_VSCROLL : 0),
                        cfg.x, cfg.y, width, height,
                        null, null, inst, null);

  if (border_style) {
    LONG style = GetWindowLong(wnd, GWL_STYLE);
    if (strcmp (border_style, "void") == 0) {
      style &= ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME);
    }
    else {
      style &= ~(WS_CAPTION | WS_BORDER);
    }
    SetWindowLong(wnd, GWL_STYLE, style);
    SetWindowPos(wnd, null, 0, 0, 0, 0,
                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
  }

  // The input method context.
  imc = ImmGetContext(wnd);

  // Correct autoplacement, which likes to put part of the window under the
  // taskbar when the window size approaches the work area size.
  if (cfg.x == (int)CW_USEDEFAULT) {
    win_fix_position();
  }

  // Initialise the terminal.
  term_reset();
  term_resize(cfg.rows, cfg.cols);

  // Initialise the scroll bar.
  SetScrollInfo(
    wnd, SB_VERT,
    &(SCROLLINFO){
      .cbSize = sizeof(SCROLLINFO),
      .fMask = SIF_ALL | SIF_DISABLENOSCROLL,
      .nMin = 0, .nMax = cfg.rows - 1,
      .nPage = cfg.rows, .nPos = 0,
    },
    false
  );

  // Set up an empty caret bitmap. We're painting the cursor manually.
  caretbm = CreateBitmap(1, font_height, 1, 1, newn(short, font_height));
  CreateCaret(wnd, caretbm, 0, 0);

  // Initialise various other stuff.
  win_init_drop_target();
  win_init_menus();
  update_transparency();

  // Create child process.
  child_create(
    argv, &(struct winsize){cfg.rows, cfg.cols, term_width, term_height}
  );

  // Finally show the window!
  fullscr_on_max = (cfg.window == -1);
  ShowWindow(wnd, fullscr_on_max ? SW_SHOWMAXIMIZED : cfg.window);

  // Message loop.
  for (;;) {
    MSG msg;
    while (PeekMessage(&msg, null, 0, 0, PM_REMOVE)) {
      if (msg.message == WM_QUIT)
        return msg.wParam;
      if (!IsDialogMessage(config_wnd, &msg))
        DispatchMessage(&msg);
    }
    child_proc();
  }
}
------=_20150727175807_31619
Content-Type: application/octet-stream; name="winmain.c.orig"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="winmain.c.orig"

Ly8gd2luLmMgKHBhcnQgb2YgbWludHR5KQovLyBDb3B5cmlnaHQgMjAwOC0x
MyBBbmR5IEtvcHBlCi8vIEJhc2VkIG9uIGNvZGUgZnJvbSBQdVRUWS0wLjYw
IGJ5IFNpbW9uIFRhdGhhbSBhbmQgdGVhbS4KLy8gTGljZW5zZWQgdW5kZXIg
dGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2
MyBvciBsYXRlci4KCiNpbmNsdWRlICJ3aW5wcml2LmgiCgojaW5jbHVkZSAi
dGVybS5oIgojaW5jbHVkZSAiYXBwaW5mby5oIgojaW5jbHVkZSAiY2hpbGQu
aCIKI2luY2x1ZGUgImNoYXJzZXQuaCIKCiNpbmNsdWRlIDxsb2NhbGUuaD4K
I2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRl
IDxzaGVsbGFwaS5oPgoKI2luY2x1ZGUgPHN5cy9jeWd3aW4uaD4KCkhJTlNU
QU5DRSBpbnN0OwpIV05EIHduZDsKSElNQyBpbWM7Cgpib29sIHdpbl9pc19m
dWxsX3NjcmVlbjsKCnN0YXRpYyBjaGFyICoqbWFpbl9hcmd2OwpzdGF0aWMg
aW50IG1haW5fYXJnYzsKc3RhdGljIEFUT00gY2xhc3NfYXRvbTsKCnN0YXRp
YyBpbnQgZXh0cmFfd2lkdGgsIGV4dHJhX2hlaWdodDsKc3RhdGljIGJvb2wg
ZnVsbHNjcl9vbl9tYXg7CnN0YXRpYyBib29sIHJlc2l6aW5nOwpzdGF0aWMg
Ym9vbCB0aXRsZV9zZXR0YWJsZSA9IHRydWU7CnN0YXRpYyBib29sIGRhZW1v
bml6ZSA9IGZhbHNlOwpzdGF0aWMgc3RyaW5nIGJvcmRlcl9zdHlsZSA9IDA7
CgpzdGF0aWMgSEJJVE1BUCBjYXJldGJtOwoKI2lmIFdJTlZFUiA8IDB4NjAw
Cgp0eXBlZGVmIHN0cnVjdCB7CiAgaW50IGN4TGVmdFdpZHRoOwogIGludCBj
eFJpZ2h0V2lkdGg7CiAgaW50IGN5VG9wSGVpZ2h0OwogIGludCBjeUJvdHRv
bUhlaWdodDsKfSBNQVJHSU5TOwoKI2VuZGlmCgpzdGF0aWMgSFJFU1VMVCAo
V0lOQVBJICpwRHdtSXNDb21wb3NpdGlvbkVuYWJsZWQpKEJPT0wgKik7CnN0
YXRpYyBIUkVTVUxUIChXSU5BUEkgKnBEd21FeHRlbmRGcmFtZUludG9DbGll
bnRBcmVhKShIV05ELCBjb25zdCBNQVJHSU5TICopOwoKLy8gSGVscGVyIGZv
ciBsb2FkaW5nIGEgc3lzdGVtIGxpYnJhcnkuIFVzaW5nIExvYWRMaWJyYXJ5
KCkgZGlyZWN0bHkgaXMgaW5zZWN1cmUKLy8gYmVjYXVzZSBXaW5kb3dzIG1p
Z2h0IGJlIHNlYXJjaGluZyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9y
eSBmaXJzdC4Kc3RhdGljIEhNT0RVTEUKbG9hZF9zeXNfbGlicmFyeShzdHJp
bmcgbmFtZSkKewogIGNoYXIgcGF0aFtNQVhfUEFUSF07CiAgdWludCBsZW4g
PSBHZXRTeXN0ZW1EaXJlY3RvcnkocGF0aCwgTUFYX1BBVEgpOwogIGlmIChs
ZW4gJiYgbGVuICsgc3RybGVuKG5hbWUpICsgMSA8IE1BWF9QQVRIKSB7CiAg
ICBwYXRoW2xlbl0gPSAnXFwnOwogICAgc3RyY3B5KCZwYXRoW2xlbiArIDFd
LCBuYW1lKTsKICAgIHJldHVybiBMb2FkTGlicmFyeShwYXRoKTsKICB9CiAg
ZWxzZQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkCmxvYWRfZHdtX2Z1
bmNzKHZvaWQpCnsKICBITU9EVUxFIGR3bSA9IGxvYWRfc3lzX2xpYnJhcnko
ImR3bWFwaS5kbGwiKTsKICBpZiAoZHdtKSB7CiAgICBwRHdtSXNDb21wb3Np
dGlvbkVuYWJsZWQgPQogICAgICAodm9pZCAqKUdldFByb2NBZGRyZXNzKGR3
bSwgIkR3bUlzQ29tcG9zaXRpb25FbmFibGVkIik7CiAgICBwRHdtRXh0ZW5k
RnJhbWVJbnRvQ2xpZW50QXJlYSA9CiAgICAgICh2b2lkICopR2V0UHJvY0Fk
ZHJlc3MoZHdtLCAiRHdtRXh0ZW5kRnJhbWVJbnRvQ2xpZW50QXJlYSIpOwog
IH0KfQoKdm9pZAp3aW5fc2V0X3RpbWVyKHZvaWQgKCpjYikodm9pZCksIHVp
bnQgdGlja3MpCnsgU2V0VGltZXIod25kLCAoVUlOVF9QVFIpY2IsIHRpY2tz
LCBudWxsKTsgfQoKdm9pZAp3aW5fc2V0X3RpdGxlKGNoYXIgKnRpdGxlKQp7
CiAgaWYgKHRpdGxlX3NldHRhYmxlKSB7CiAgICB3Y2hhciB3dGl0bGVbc3Ry
bGVuKHRpdGxlKSArIDFdOwogICAgaWYgKGNzX21ic3Rvd2NzKHd0aXRsZSwg
dGl0bGUsIGxlbmd0aG9mKHd0aXRsZSkpID49IDApCiAgICAgIFNldFdpbmRv
d1RleHRXKHduZCwgd3RpdGxlKTsKICB9Cn0KCnZvaWQKd2luX2NvcHlfdGl0
bGUodm9pZCkKewogIGludCBsZW4gPSBHZXRXaW5kb3dUZXh0TGVuZ3RoVyh3
bmQpOwogIHdjaGFyIHRpdGxlW2xlbiArIDFdOwogIGxlbiA9IEdldFdpbmRv
d1RleHRXKHduZCwgdGl0bGUsIGxlbiArIDEpOwogIHdpbl9jb3B5KHRpdGxl
LCAwLCBsZW4gKyAxKTsKfQoKdm9pZAp3aW5fcHJlZml4X3RpdGxlKGNvbnN0
IGNoYXIgKiBwcmVmaXgpCnsKICBpbnQgbGVuID0gR2V0V2luZG93VGV4dExl
bmd0aFcod25kKTsKICB3Y2hhciBwdGl0bGVbc3RybGVuKHByZWZpeCkgKyBs
ZW4gKyAxXTsKICBpbnQgcGxlbiA9IGNzX21ic3Rvd2NzKHB0aXRsZSwgcHJl
Zml4LCBsZW5ndGhvZihwdGl0bGUpKTsKICB3Y2hhciAqIHRpdGxlID0gJiBw
dGl0bGVbcGxlbl07CiAgbGVuID0gR2V0V2luZG93VGV4dFcod25kLCB0aXRs
ZSwgbGVuICsgMSk7CiAgU2V0V2luZG93VGV4dFcod25kLCBwdGl0bGUpOwp9
CgovKgogKiBUaXRsZSBzdGFjayAoaW1wbGVtZW50ZWQgYXMgZml4ZWQtc2l6
ZSBjaXJjdWxhciBidWZmZXIpCiAqLwpzdGF0aWMgd3N0cmluZyB0aXRsZXNb
MTZdOwpzdGF0aWMgdWludCB0aXRsZXNfaTsKCnZvaWQKd2luX3NhdmVfdGl0
bGUodm9pZCkKewogIGludCBsZW4gPSBHZXRXaW5kb3dUZXh0TGVuZ3RoVyh3
bmQpOwogIHdjaGFyICp0aXRsZSA9IG5ld24od2NoYXIsIGxlbiArIDEpOwog
IEdldFdpbmRvd1RleHRXKHduZCwgdGl0bGUsIGxlbiArIDEpOwogIGRlbGV0
ZSh0aXRsZXNbdGl0bGVzX2ldKTsKICB0aXRsZXNbdGl0bGVzX2krK10gPSB0
aXRsZTsKICBpZiAodGl0bGVzX2kgPT0gbGVuZ3Rob2YodGl0bGVzKSkKICAg
IHRpdGxlc19pID0gMDsKfQoKdm9pZAp3aW5fcmVzdG9yZV90aXRsZSh2b2lk
KQp7CiAgaWYgKCF0aXRsZXNfaSkKICAgIHRpdGxlc19pID0gbGVuZ3Rob2Yo
dGl0bGVzKTsKICB3c3RyaW5nIHRpdGxlID0gdGl0bGVzWy0tdGl0bGVzX2ld
OwogIGlmICh0aXRsZSkgewogICAgU2V0V2luZG93VGV4dFcod25kLCB0aXRs
ZSk7CiAgICBkZWxldGUodGl0bGUpOwogICAgdGl0bGVzW3RpdGxlc19pXSA9
IDA7CiAgfQp9CgovKgogKiAgU3dpdGNoIHRvIG5leHQgb3IgcHJldmlvdXMg
YXBwbGljYXRpb24gd2luZG93IGluIHotb3JkZXIKICovCgpzdGF0aWMgSFdO
RCBmaXJzdF93bmQsIGxhc3Rfd25kOwoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sK
d25kX2VudW1fcHJvYyhIV05EIGN1cnJfd25kLCBMUEFSQU0gdW51c2VkKGxw
KSkgewogIGlmIChjdXJyX3duZCAhPSB3bmQgJiYgIUlzSWNvbmljKGN1cnJf
d25kKSkgewogICAgV0lORE9XSU5GTyBjdXJyX3duZF9pbmZvOwogICAgY3Vy
cl93bmRfaW5mby5jYlNpemUgPSBzaXplb2YoV0lORE9XSU5GTyk7CiAgICBH
ZXRXaW5kb3dJbmZvKGN1cnJfd25kLCAmY3Vycl93bmRfaW5mbyk7CiAgICBp
ZiAoY2xhc3NfYXRvbSA9PSBjdXJyX3duZF9pbmZvLmF0b21XaW5kb3dUeXBl
KSB7CiAgICAgIGZpcnN0X3duZCA9IGZpcnN0X3duZCA/OiBjdXJyX3duZDsK
ICAgICAgbGFzdF93bmQgPSBjdXJyX3duZDsKICAgIH0KICB9CiAgcmV0dXJu
IHRydWU7Cn0KCnZvaWQKd2luX3N3aXRjaChib29sIGJhY2ssIGJvb2wgYWx0
ZXJuYXRlKQp7CiAgZmlyc3Rfd25kID0gMCwgbGFzdF93bmQgPSAwOwogIEVu
dW1XaW5kb3dzKHduZF9lbnVtX3Byb2MsIDApOwogIGlmIChmaXJzdF93bmQp
IHsKICAgIGlmIChiYWNrKQogICAgICBmaXJzdF93bmQgPSBsYXN0X3duZDsK
ICAgIGVsc2UKICAgICAgU2V0V2luZG93UG9zKHduZCwgbGFzdF93bmQsIDAs
IDAsIDAsIDAsIFNXUF9OT01PVkUgfCBTV1BfTk9TSVpFCiAgICAgICAgICAg
ICAgICAgICAgICAgfCAoYWx0ZXJuYXRlID8gU1dQX05PWk9SREVSIDogU1dQ
X05PUkVQT1NJVElPTikpOwogICAgQnJpbmdXaW5kb3dUb1RvcChmaXJzdF93
bmQpOwogIH0KfQoKc3RhdGljIHZvaWQKZ2V0X21vbml0b3JfaW5mbyhNT05J
VE9SSU5GTyAqbWlwKQp7CiAgSE1PTklUT1IgbW9uID0gTW9uaXRvckZyb21X
aW5kb3cod25kLCBNT05JVE9SX0RFRkFVTFRUT05FQVJFU1QpOwogIG1pcC0+
Y2JTaXplID0gc2l6ZW9mKE1PTklUT1JJTkZPKTsKICBHZXRNb25pdG9ySW5m
byhtb24sIG1pcCk7Cn0KCi8qCiAqIE1pbmltaXNlIG9yIHJlc3RvcmUgdGhl
IHdpbmRvdyBpbiByZXNwb25zZSB0byBhIHNlcnZlci1zaWRlCiAqIHJlcXVl
c3QuCiAqLwp2b2lkCndpbl9zZXRfaWNvbmljKGJvb2wgaWNvbmljKQp7CiAg
aWYgKGljb25pYyBeIElzSWNvbmljKHduZCkpCiAgICBTaG93V2luZG93KHdu
ZCwgaWNvbmljID8gU1dfTUlOSU1JWkUgOiBTV19SRVNUT1JFKTsKfQoKLyoK
ICogTW92ZSB0aGUgd2luZG93IGluIHJlc3BvbnNlIHRvIGEgc2VydmVyLXNp
ZGUgcmVxdWVzdC4KICovCnZvaWQKd2luX3NldF9wb3MoaW50IHgsIGludCB5
KQp7CiAgdHJhY2VfcmVzaXplKCgiLS0tIHdpbl9zZXRfcG9zICVkICVkXG4i
LCB4LCB5KSk7CiAgaWYgKCFJc1pvb21lZCh3bmQpKQogICAgU2V0V2luZG93
UG9zKHduZCwgbnVsbCwgeCwgeSwgMCwgMCwgU1dQX05PU0laRSB8IFNXUF9O
T1pPUkRFUik7Cn0KCi8qCiAqIE1vdmUgdGhlIHdpbmRvdyB0byB0aGUgdG9w
IG9yIGJvdHRvbSBvZiB0aGUgei1vcmRlciBpbiByZXNwb25zZQogKiB0byBh
IHNlcnZlci1zaWRlIHJlcXVlc3QuCiAqLwp2b2lkCndpbl9zZXRfem9yZGVy
KGJvb2wgdG9wKQp7CiAgU2V0V2luZG93UG9zKHduZCwgdG9wID8gSFdORF9U
T1AgOiBIV05EX0JPVFRPTSwgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAg
U1dQX05PTU9WRSB8IFNXUF9OT1NJWkUpOwp9Cgpib29sCndpbl9pc19pY29u
aWModm9pZCkKewogIHJldHVybiBJc0ljb25pYyh3bmQpOwp9Cgp2b2lkCndp
bl9nZXRfcG9zKGludCAqeHAsIGludCAqeXApCnsKICBSRUNUIHI7CiAgR2V0
V2luZG93UmVjdCh3bmQsICZyKTsKICAqeHAgPSByLmxlZnQ7CiAgKnlwID0g
ci50b3A7Cn0KCnZvaWQKd2luX2dldF9waXhlbHMoaW50ICpoZWlnaHRfcCwg
aW50ICp3aWR0aF9wKQp7CiAgUkVDVCByOwogIEdldFdpbmRvd1JlY3Qod25k
LCAmcik7CiAgKmhlaWdodF9wID0gci5ib3R0b20gLSByLnRvcDsKICAqd2lk
dGhfcCA9IHIucmlnaHQgLSByLmxlZnQ7Cn0KCnZvaWQKd2luX2dldF9zY3Jl
ZW5fY2hhcnMoaW50ICpyb3dzX3AsIGludCAqY29sc19wKQp7CiAgTU9OSVRP
UklORk8gbWk7CiAgZ2V0X21vbml0b3JfaW5mbygmbWkpOwogIFJFQ1QgZnIg
PSBtaS5yY01vbml0b3I7CiAgKnJvd3NfcCA9IChmci5ib3R0b20gLSBmci50
b3ApIC8gZm9udF9oZWlnaHQ7CiAgKmNvbHNfcCA9IChmci5yaWdodCAtIGZy
LmxlZnQpIC8gZm9udF93aWR0aDsKfQoKdm9pZAp3aW5fc2V0X3BpeGVscyhp
bnQgaGVpZ2h0LCBpbnQgd2lkdGgpCnsKICB0cmFjZV9yZXNpemUoKCItLS0g
d2luX3NldF9waXhlbHMgJWQgJWRcbiIsIGhlaWdodCwgd2lkdGgpKTsKICBT
ZXRXaW5kb3dQb3Mod25kLCBudWxsLCAwLCAwLAogICAgICAgICAgICAgICB3
aWR0aCArIDIgKiBQQURESU5HICsgZXh0cmFfd2lkdGgsCiAgICAgICAgICAg
ICAgIGhlaWdodCArIDIgKiBQQURESU5HICsgZXh0cmFfaGVpZ2h0LAogICAg
ICAgICAgICAgICBTV1BfTk9BQ1RJVkFURSB8IFNXUF9OT0NPUFlCSVRTIHwg
U1dQX05PTU9WRSB8IFNXUF9OT1pPUkRFUik7Cn0KCnN0YXRpYyB2b2lkCndp
bl9maXhfcG9zaXRpb24odm9pZCkKewogICAgUkVDVCB3cjsKICAgIEdldFdp
bmRvd1JlY3Qod25kLCAmd3IpOwogICAgTU9OSVRPUklORk8gbWk7CiAgICBn
ZXRfbW9uaXRvcl9pbmZvKCZtaSk7CiAgICBSRUNUIGFyID0gbWkucmNXb3Jr
OwoKICAgIC8vIENvcnJlY3QgZWRnZXMuIFRvcCBhbmQgbGVmdCB3aW4gaWYg
dGhlIHdpbmRvdyBpcyB0b28gYmlnLgogICAgd3IubGVmdCAtPSBtYXgoMCwg
d3IucmlnaHQgLSBhci5yaWdodCk7CiAgICB3ci50b3AgLT0gbWF4KDAsIHdy
LmJvdHRvbSAtIGFyLmJvdHRvbSk7CiAgICB3ci5sZWZ0ID0gbWF4KHdyLmxl
ZnQsIGFyLmxlZnQpOwogICAgd3IudG9wID0gbWF4KHdyLnRvcCwgYXIudG9w
KTsKCiAgICBTZXRXaW5kb3dQb3Mod25kLCAwLCB3ci5sZWZ0LCB3ci50b3As
IDAsIDAsCiAgICAgICAgICAgICAgICAgU1dQX05PU0laRSB8IFNXUF9OT1pP
UkRFUiB8IFNXUF9OT0FDVElWQVRFKTsKfQoKdm9pZAp3aW5fc2V0X2NoYXJz
KGludCByb3dzLCBpbnQgY29scykKewogIHRyYWNlX3Jlc2l6ZSgoIi0tLSB3
aW5fc2V0X2NoYXJzICVkw5clZFxuIiwgcm93cywgY29scykpOwogIHdpbl9z
ZXRfcGl4ZWxzKHJvd3MgKiBmb250X2hlaWdodCwgY29scyAqIGZvbnRfd2lk
dGgpOwogIHdpbl9maXhfcG9zaXRpb24oKTsKfQoKCi8vIENsb2Nrd29yawpp
bnQgZ2V0X3RpY2tfY291bnQodm9pZCkgeyByZXR1cm4gR2V0VGlja0NvdW50
KCk7IH0KaW50IGN1cnNvcl9ibGlua190aWNrcyh2b2lkKSB7IHJldHVybiBH
ZXRDYXJldEJsaW5rVGltZSgpOyB9CgpzdGF0aWMgdm9pZApmbGFzaF90YXNr
YmFyKGJvb2wgZW5hYmxlKQp7CiAgc3RhdGljIGJvb2wgZW5hYmxlZDsKICBp
ZiAoZW5hYmxlICE9IGVuYWJsZWQpIHsKICAgIEZsYXNoV2luZG93RXgoJihG
TEFTSFdJTkZPKXsKICAgICAgLmNiU2l6ZSA9IHNpemVvZihGTEFTSFdJTkZP
KSwKICAgICAgLmh3bmQgPSB3bmQsCiAgICAgIC5kd0ZsYWdzID0gZW5hYmxl
ID8gRkxBU0hXX1RSQVkgfCBGTEFTSFdfVElNRVIgOiBGTEFTSFdfU1RPUCwK
ICAgICAgLnVDb3VudCA9IDEsCiAgICAgIC5kd1RpbWVvdXQgPSAwCiAgICB9
KTsKICAgIGVuYWJsZWQgPSBlbmFibGU7CiAgfQp9CgovKgogKiBCZWxsLgog
Ki8Kdm9pZAp3aW5fYmVsbCh2b2lkKQp7CiAgaWYgKGNmZy5iZWxsX3NvdW5k
IHx8IGNmZy5iZWxsX3R5cGUpIHsKICAgIGlmIChjZmcuYmVsbF9mcmVxKQog
ICAgICBCZWVwKGNmZy5iZWxsX2ZyZXEsIGNmZy5iZWxsX2xlbik7CiAgICBl
bHNlIHsKICAgICAgLy8gMCAgTUJfT0sgICAgICAgICAgICAgICBEZWZhdWx0
IEJlZXAKICAgICAgLy8gMSAgTUJfSUNPTlNUT1AgICAgICAgICBDcml0aWNh
bCBTdG9wCiAgICAgIC8vIDIgIE1CX0lDT05RVUVTVElPTiAgICAgUXVlc3Rp
b24KICAgICAgLy8gMyAgTUJfSUNPTkVYQ0xBTUFUSU9OICBFeGNsYW1hdGlv
bgogICAgICAvLyA0ICBNQl9JQ09OQVNURVJJU0sgICAgIEFzdGVyaXNrCiAg
ICAgIC8vID8gIDB4RkZGRkZGRkYgICAgICAgICAgU2ltcGxlIEJlZXAKICAg
ICAgTWVzc2FnZUJlZXAoKGNmZy5iZWxsX3R5cGUgLSAxKSAqIDE2KTsKICAg
IH0KICB9CiAgaWYgKGNmZy5iZWxsX3Rhc2tiYXIgJiYgIXRlcm0uaGFzX2Zv
Y3VzKQogICAgZmxhc2hfdGFza2Jhcih0cnVlKTsKfQoKdm9pZAp3aW5faW52
YWxpZGF0ZV9hbGwodm9pZCkKewogIEludmFsaWRhdGVSZWN0KHduZCwgbnVs
bCwgdHJ1ZSk7Cn0KCnZvaWQKd2luX2FkYXB0X3Rlcm1fc2l6ZShib29sIHN5
bmNfc2l6ZV93aXRoX2ZvbnQsIGJvb2wgc2NhbGVfZm9udF93aXRoX3NpemUp
CnsKICB0cmFjZV9yZXNpemUoKCItLS0gd2luX2FkYXB0X3Rlcm1fc2l6ZSBm
dWxsICVkIFpvb21lZCAlZFxuIiwgd2luX2lzX2Z1bGxzY3JlZW4sIElzWm9v
bWVkKHduZCkpKTsKICBpZiAoSXNJY29uaWMod25kKSkKICAgIHJldHVybjsK
CiAgaWYgKHN5bmNfc2l6ZV93aXRoX2ZvbnQgJiYgIXdpbl9pc19mdWxsc2Ny
ZWVuKSB7CiAgICB3aW5fc2V0X2NoYXJzKHRlcm0ucm93cywgdGVybS5jb2xz
KTsKICAgIC8vd2luX2ZpeF9wb3NpdGlvbigpOwogICAgd2luX2ludmFsaWRh
dGVfYWxsKCk7CiAgICByZXR1cm47CiAgfQoKIC8qIEN1cnJlbnQgd2luZG93
IHNpemVzIC4uLiAqLwogIFJFQ1QgY3IsIHdyOwogIEdldENsaWVudFJlY3Qo
d25kLCAmY3IpOwogIEdldFdpbmRvd1JlY3Qod25kLCAmd3IpOwogIGludCBj
bGllbnRfd2lkdGggPSBjci5yaWdodCAtIGNyLmxlZnQ7CiAgaW50IGNsaWVu
dF9oZWlnaHQgPSBjci5ib3R0b20gLSBjci50b3A7CiAgZXh0cmFfd2lkdGgg
PSB3ci5yaWdodCAtIHdyLmxlZnQgLSBjbGllbnRfd2lkdGg7CiAgZXh0cmFf
aGVpZ2h0ID0gd3IuYm90dG9tIC0gd3IudG9wIC0gY2xpZW50X2hlaWdodDsK
ICBpbnQgdGVybV93aWR0aCA9IGNsaWVudF93aWR0aCAtIDIgKiBQQURESU5H
OwogIGludCB0ZXJtX2hlaWdodCA9IGNsaWVudF9oZWlnaHQgLSAyICogUEFE
RElORzsKCiAgaWYgKHNjYWxlX2ZvbnRfd2l0aF9zaXplKSB7CiAgICAvLyBj
YWxjIHByZWxpbWluYXJ5IHNpemUgKHdpdGhvdXQgZm9udCBzY2FsaW5nKSwg
YXMgYmVsb3cKICAgIC8vIHNob3VsZCB1c2UgdGVybV9oZWlnaHQgcmF0aGVy
IHRoYW4gcm93czsgY2FsYyBhbmQgc3RvcmUgaW4gdGVybV9yZXNpemUKICAg
IGludCBjb2xzMCA9IG1heCgxLCB0ZXJtX3dpZHRoIC8gZm9udF93aWR0aCk7
CiAgICBpbnQgcm93czAgPSBtYXgoMSwgdGVybV9oZWlnaHQgLyBmb250X2hl
aWdodCk7CgogICAgLy8gcm93czAvdGVybS5yb3dzIGdpdmVzIGEgcm91Z2gg
c2NhbGluZyBmYWN0b3IgZm9yIGZvbnRfaGVpZ2h0CiAgICAvLyBjb2xzMC90
ZXJtLmNvbHMgZ2l2ZXMgYSByb3VnaCBzY2FsaW5nIGZhY3RvciBmb3IgZm9u
dF93aWR0aAogICAgLy8gZm9udF9oZWlnaHQsIGZvbnRfd2lkdGggZ2l2ZSBh
IHJvdWdoIHNjYWxpbmcgaW5kaWNhdGlvbiBmb3IgZm9udF9zaXplCiAgICAv
LyBoZWlnaHQgb3Igd2lkdGggY291bGQgYmUgY29uc2lkZXJlZCBtb3JlIGFj
Y29yZGluZyB0byBwcmVmZXJlbmNlCiAgICBib29sIGJpZ2dlciA9IHJvd3Mw
ICogY29sczAgPiB0ZXJtLnJvd3MgKiB0ZXJtLmNvbHM7CiAgICBpbnQgZm9u
dF9zaXplMSA9CiAgICAgIC8vIGhldXJpc3RpYyBiZXN0IGFwcHJvYWNoIHRh
a2VuLi4uCiAgICAgIC8vIGJpZ2dlcgogICAgICAvLyAgID8gbWF4KGZvbnRf
c2l6ZSAqIHJvd3MwIC8gdGVybS5yb3dzLCBmb250X3NpemUgKiBjb2xzMCAv
IHRlcm0uY29scykKICAgICAgLy8gICA6IG1pbihmb250X3NpemUgKiByb3dz
MCAvIHRlcm0ucm93cywgZm9udF9zaXplICogY29sczAgLyB0ZXJtLmNvbHMp
OwogICAgICAvLyBiaWdnZXIKICAgICAgLy8gICA/IGZvbnRfc2l6ZSAqIHJv
d3MwIC8gdGVybS5yb3dzICsgMgogICAgICAvLyAgIDogZm9udF9zaXplICog
cm93czAgLyB0ZXJtLnJvd3M7CiAgICAgIGJpZ2dlcgogICAgICAgID8gKGZv
bnRfc2l6ZSAqIHJvd3MwIC8gdGVybS5yb3dzICsgZm9udF9zaXplICogY29s
czAgLyB0ZXJtLmNvbHMpIC8gMiArIDEKICAgICAgICA6IChmb250X3NpemUg
KiByb3dzMCAvIHRlcm0ucm93cyArIGZvbnRfc2l6ZSAqIGNvbHMwIC8gdGVy
bS5jb2xzKSAvIDI7CiAgICAgIC8vIGJpZ2dlcgogICAgICAvLyAgID8gZm9u
dF9zaXplICogcm93czAgKiBjb2xzMCAvICh0ZXJtLnJvd3MgKiB0ZXJtLmNv
bHMpCiAgICAgIC8vICAgOiBmb250X3NpemUgKiByb3dzMCAqIGNvbHMwIC8g
KHRlcm0ucm93cyAqIHRlcm0uY29scyk7CiAgICAgIHRyYWNlX3Jlc2l6ZSgo
InRlcm0gc2l6ZSAlZCAlZCAtPiAlZCAlZFxuIiwgdGVybS5yb3dzLCB0ZXJt
LmNvbHMsIHJvd3MwLCBjb2xzMCkpOwogICAgICB0cmFjZV9yZXNpemUoKCJm
b250IHNpemUgJWQgLT4gJWRcbiIsIGZvbnRfc2l6ZSwgZm9udF9zaXplMSkp
OwoKICAgIGlmIChmb250X3NpemUxICE9IGZvbnRfc2l6ZSkKICAgICAgd2lu
X3NldF9mb250X3NpemUoZm9udF9zaXplMSwgZmFsc2UpOwogIH0KCiAgaW50
IGNvbHMgPSBtYXgoMSwgdGVybV93aWR0aCAvIGZvbnRfd2lkdGgpOwogIGlu
dCByb3dzID0gbWF4KDEsIHRlcm1faGVpZ2h0IC8gZm9udF9oZWlnaHQpOwog
IGlmIChyb3dzICE9IHRlcm0ucm93cyB8fCBjb2xzICE9IHRlcm0uY29scykg
ewogICAgdGVybV9yZXNpemUocm93cywgY29scyk7CiAgICBzdHJ1Y3Qgd2lu
c2l6ZSB3cyA9IHtyb3dzLCBjb2xzLCBjb2xzICogZm9udF93aWR0aCwgcm93
cyAqIGZvbnRfaGVpZ2h0fTsKICAgIGNoaWxkX3Jlc2l6ZSgmd3MpOwogIH0K
ICB3aW5faW52YWxpZGF0ZV9hbGwoKTsKfQoKYm9vbAp3aW5faXNfZ2xhc3Nf
YXZhaWxhYmxlKHZvaWQpCnsKICBCT09MIHJlc3VsdCA9IGZhbHNlOwogIGlm
IChwRHdtSXNDb21wb3NpdGlvbkVuYWJsZWQpCiAgICBwRHdtSXNDb21wb3Np
dGlvbkVuYWJsZWQoJnJlc3VsdCk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKc3Rh
dGljIHZvaWQKdXBkYXRlX2dsYXNzKHZvaWQpCnsKICBpZiAocER3bUV4dGVu
ZEZyYW1lSW50b0NsaWVudEFyZWEpIHsKICAgIGJvb2wgZW5hYmxlZCA9CiAg
ICAgIGNmZy50cmFuc3BhcmVuY3kgPT0gVFJfR0xBU1MgJiYgIXdpbl9pc19m
dWxsc2NyZWVuICYmCiAgICAgICEoY2ZnLm9wYXF1ZV93aGVuX2ZvY3VzZWQg
JiYgdGVybS5oYXNfZm9jdXMpOwogICAgcER3bUV4dGVuZEZyYW1lSW50b0Ns
aWVudEFyZWEod25kLCAmKE1BUkdJTlMpe2VuYWJsZWQgPyAtMSA6IDAsIDAs
IDAsIDB9KTsKICB9Cn0KCi8qCiAqIEdvIGZ1bGwtc2NyZWVuLiBUaGlzIHNo
b3VsZCBvbmx5IGJlIGNhbGxlZCB3aGVuIHdlIGFyZSBhbHJlYWR5CiAqIG1h
eGltaXNlZC4KICovCnN0YXRpYyB2b2lkCm1ha2VfZnVsbHNjcmVlbih2b2lk
KQp7CiAgd2luX2lzX2Z1bGxzY3JlZW4gPSB0cnVlOwoKIC8qIFJlbW92ZSB0
aGUgd2luZG93IGZ1cm5pdHVyZS4gKi8KICBMT05HIHN0eWxlID0gR2V0V2lu
ZG93TG9uZyh3bmQsIEdXTF9TVFlMRSk7CiAgc3R5bGUgJj0gfihXU19DQVBU
SU9OIHwgV1NfQk9SREVSIHwgV1NfVEhJQ0tGUkFNRSk7CiAgU2V0V2luZG93
TG9uZyh3bmQsIEdXTF9TVFlMRSwgc3R5bGUpOwoKIC8qIFRoZSBnbGFzcyBl
ZmZlY3QgZG9lc24ndCB3b3JrIGZvciBmdWxsc2NyZWVuIHdpbmRvd3MgKi8K
ICB1cGRhdGVfZ2xhc3MoKTsKCiAvKiBSZXNpemUgb3Vyc2VsdmVzIHRvIGV4
YWN0bHkgY292ZXIgdGhlIG5lYXJlc3QgbW9uaXRvci4gKi8KICBNT05JVE9S
SU5GTyBtaTsKICBnZXRfbW9uaXRvcl9pbmZvKCZtaSk7CiAgUkVDVCBmciA9
IG1pLnJjTW9uaXRvcjsKICBTZXRXaW5kb3dQb3Mod25kLCBIV05EX1RPUCwg
ZnIubGVmdCwgZnIudG9wLAogICAgICAgICAgICAgICBmci5yaWdodCAtIGZy
LmxlZnQsIGZyLmJvdHRvbSAtIGZyLnRvcCwgU1dQX0ZSQU1FQ0hBTkdFRCk7
Cn0KCi8qCiAqIENsZWFyIHRoZSBmdWxsLXNjcmVlbiBhdHRyaWJ1dGVzLgog
Ki8Kc3RhdGljIHZvaWQKY2xlYXJfZnVsbHNjcmVlbih2b2lkKQp7CiAgd2lu
X2lzX2Z1bGxzY3JlZW4gPSBmYWxzZTsKICB1cGRhdGVfZ2xhc3MoKTsKCiAv
KiBSZWluc3RhdGUgdGhlIHdpbmRvdyBmdXJuaXR1cmUuICovCiAgTE9ORyBz
dHlsZSA9IEdldFdpbmRvd0xvbmcod25kLCBHV0xfU1RZTEUpOwogIGlmIChi
b3JkZXJfc3R5bGUpIHsKICAgIGlmIChzdHJjbXAgKGJvcmRlcl9zdHlsZSwg
InZvaWQiKSAhPSAwKSB7CiAgICAgIHN0eWxlIHw9IFdTX1RISUNLRlJBTUU7
CiAgICB9CiAgfQogIGVsc2UgewogICAgc3R5bGUgfD0gV1NfQ0FQVElPTiB8
IFdTX0JPUkRFUiB8IFdTX1RISUNLRlJBTUU7CiAgfQogIFNldFdpbmRvd0xv
bmcod25kLCBHV0xfU1RZTEUsIHN0eWxlKTsKICBTZXRXaW5kb3dQb3Mod25k
LCBudWxsLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICBTV1BfTk9NT1ZF
IHwgU1dQX05PU0laRSB8IFNXUF9OT1pPUkRFUiB8IFNXUF9GUkFNRUNIQU5H
RUQpOwp9CgovKgogKiBNYXhpbWlzZSBvciByZXN0b3JlIHRoZSB3aW5kb3cg
aW4gcmVzcG9uc2UgdG8gYSBzZXJ2ZXItc2lkZSByZXF1ZXN0LgogKiBBcmd1
bWVudCB2YWx1ZSBvZiAyIG1lYW5zIGdvIGZ1bGxzY3JlZW4uCiAqLwp2b2lk
Cndpbl9tYXhpbWlzZShpbnQgbWF4KQp7CiAgaWYgKG1heCA9PSAtMikgLy8g
dG9nZ2xlIGZ1bGwgc2NyZWVuCiAgICBtYXggPSB3aW5faXNfZnVsbHNjcmVl
biA/IDAgOiAyOwogIGlmIChJc1pvb21lZCh3bmQpKSB7CiAgICBpZiAoIW1h
eCkKICAgICAgU2hvd1dpbmRvdyh3bmQsIFNXX1JFU1RPUkUpOwogICAgZWxz
ZSBpZiAobWF4ID09IDIgJiYgIXdpbl9pc19mdWxsc2NyZWVuKQogICAgICBt
YWtlX2Z1bGxzY3JlZW4oKTsKICB9CiAgZWxzZSBpZiAobWF4KSB7CiAgICBp
ZiAobWF4ID09IDIpCiAgICAgIGZ1bGxzY3Jfb25fbWF4ID0gdHJ1ZTsKICAg
IFNob3dXaW5kb3cod25kLCBTV19NQVhJTUlaRSk7CiAgfQp9CgovKgogKiBH
byBiYWNrIHRvIGNvbmZpZ3VyZWQgd2luZG93IHNpemUuCiAqLwpzdGF0aWMg
dm9pZApkZWZhdWx0X3NpemUodm9pZCkKewogIGlmIChJc1pvb21lZCh3bmQp
KQogICAgU2hvd1dpbmRvdyh3bmQsIFNXX1JFU1RPUkUpOwogIHdpbl9zZXRf
Y2hhcnMoY2ZnLnJvd3MsIGNmZy5jb2xzKTsKfQoKc3RhdGljIHZvaWQKdXBk
YXRlX3RyYW5zcGFyZW5jeSh2b2lkKQp7CiAgaW50IHRyYW5zID0gY2ZnLnRy
YW5zcGFyZW5jeTsKICBpZiAodHJhbnMgPT0gVFJfR0xBU1MpCiAgICB0cmFu
cyA9IDA7CiAgTE9ORyBzdHlsZSA9IEdldFdpbmRvd0xvbmcod25kLCBHV0xf
RVhTVFlMRSk7CiAgc3R5bGUgPSB0cmFucyA/IHN0eWxlIHwgV1NfRVhfTEFZ
RVJFRCA6IHN0eWxlICYgfldTX0VYX0xBWUVSRUQ7CiAgU2V0V2luZG93TG9u
Zyh3bmQsIEdXTF9FWFNUWUxFLCBzdHlsZSk7CiAgaWYgKHRyYW5zKSB7CiAg
ICBpZiAoY2ZnLm9wYXF1ZV93aGVuX2ZvY3VzZWQgJiYgdGVybS5oYXNfZm9j
dXMpCiAgICAgIHRyYW5zID0gMDsKICAgIFNldExheWVyZWRXaW5kb3dBdHRy
aWJ1dGVzKHduZCwgMCwgMjU1IC0gKHVjaGFyKXRyYW5zLCBMV0FfQUxQSEEp
OwogIH0KCiAgdXBkYXRlX2dsYXNzKCk7Cn0KCnZvaWQKd2luX3VwZGF0ZV9z
Y3JvbGxiYXIodm9pZCkKewogIGludCBzY3JvbGxiYXIgPSB0ZXJtLnNob3df
c2Nyb2xsYmFyID8gY2ZnLnNjcm9sbGJhciA6IDA7CiAgTE9ORyBzdHlsZSA9
IEdldFdpbmRvd0xvbmcod25kLCBHV0xfU1RZTEUpOwogIFNldFdpbmRvd0xv
bmcod25kLCBHV0xfU1RZTEUsCiAgICAgICAgICAgICAgICBzY3JvbGxiYXIg
PyBzdHlsZSB8IFdTX1ZTQ1JPTEwgOiBzdHlsZSAmIH5XU19WU0NST0xMKTsK
ICBMT05HIGV4c3R5bGUgPSBHZXRXaW5kb3dMb25nKHduZCwgR1dMX0VYU1RZ
TEUpOwogIFNldFdpbmRvd0xvbmcod25kLCBHV0xfRVhTVFlMRSwKICAgICAg
ICAgICAgICAgIHNjcm9sbGJhciA8IDAgPyBleHN0eWxlIHwgV1NfRVhfTEVG
VFNDUk9MTEJBUgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGV4
c3R5bGUgJiB+V1NfRVhfTEVGVFNDUk9MTEJBUik7CiAgU2V0V2luZG93UG9z
KHduZCwgbnVsbCwgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAgU1dQX05P
QUNUSVZBVEUgfCBTV1BfTk9NT1ZFIHwKICAgICAgICAgICAgICAgU1dQX05P
U0laRSB8IFNXUF9OT1pPUkRFUiB8IFNXUF9GUkFNRUNIQU5HRUQpOwp9Cgp2
b2lkCndpbl9yZWNvbmZpZyh2b2lkKQp7CiAgdHJhY2VfcmVzaXplKCgiLS0t
IHdpbl9yZWNvbmZpZ1xuIikpOwogLyogUGFzcyBuZXcgY29uZmlnIGRhdGEg
dG8gdGhlIHRlcm1pbmFsICovCiAgdGVybV9yZWNvbmZpZygpOwoKICBib29s
IGZvbnRfY2hhbmdlZCA9CiAgICBzdHJjbXAobmV3X2NmZy5mb250Lm5hbWUs
IGNmZy5mb250Lm5hbWUpIHx8CiAgICBuZXdfY2ZnLmZvbnQuc2l6ZSAhPSBj
ZmcuZm9udC5zaXplIHx8CiAgICBuZXdfY2ZnLmZvbnQuaXNib2xkICE9IGNm
Zy5mb250LmlzYm9sZCB8fAogICAgbmV3X2NmZy5ib2xkX2FzX2ZvbnQgIT0g
Y2ZnLmJvbGRfYXNfZm9udCB8fAogICAgbmV3X2NmZy5ib2xkX2FzX2NvbG91
ciAhPSBjZmcuYm9sZF9hc19jb2xvdXIgfHwKICAgIG5ld19jZmcuZm9udF9z
bW9vdGhpbmcgIT0gY2ZnLmZvbnRfc21vb3RoaW5nOwoKICBpZiAobmV3X2Nm
Zy5mZ19jb2xvdXIgIT0gY2ZnLmZnX2NvbG91cikKICAgIHdpbl9zZXRfY29s
b3VyKEZHX0NPTE9VUl9JLCBuZXdfY2ZnLmZnX2NvbG91cik7CgogIGlmIChu
ZXdfY2ZnLmJnX2NvbG91ciAhPSBjZmcuYmdfY29sb3VyKQogICAgd2luX3Nl
dF9jb2xvdXIoQkdfQ09MT1VSX0ksIG5ld19jZmcuYmdfY29sb3VyKTsKCiAg
aWYgKG5ld19jZmcuY3Vyc29yX2NvbG91ciAhPSBjZmcuY3Vyc29yX2NvbG91
cikKICAgIHdpbl9zZXRfY29sb3VyKENVUlNPUl9DT0xPVVJfSSwgbmV3X2Nm
Zy5jdXJzb3JfY29sb3VyKTsKCiAgLyogQ29weSB0aGUgbmV3IGNvbmZpZyBh
bmQgcmVmcmVzaCBldmVyeXRoaW5nICovCiAgY29weV9jb25maWcoJmNmZywg
Jm5ld19jZmcpOwogIGlmIChmb250X2NoYW5nZWQpIHsKICAgIHdpbl9pbml0
X2ZvbnRzKGNmZy5mb250LnNpemUpOwogICAgdHJhY2VfcmVzaXplKCgiICh3
aW5fcmVjb25maWcgLT4gd2luX2FkYXB0X3Rlcm1fc2l6ZSlcbiIpKTsKICAg
IHdpbl9hZGFwdF90ZXJtX3NpemUodHJ1ZSwgZmFsc2UpOwogIH0KICB3aW5f
dXBkYXRlX3Njcm9sbGJhcigpOwogIHVwZGF0ZV90cmFuc3BhcmVuY3koKTsK
ICB3aW5fdXBkYXRlX21vdXNlKCk7CgogIGJvb2wgb2xkX2FtYmlnX3dpZGUg
PSBjc19hbWJpZ193aWRlOwogIGNzX3JlY29uZmlnKCk7CiAgaWYgKHRlcm0u
cmVwb3J0X2ZvbnRfY2hhbmdlZCAmJiBmb250X2NoYW5nZWQpCiAgICBpZiAo
dGVybS5yZXBvcnRfYW1iaWdfd2lkdGgpCiAgICAgIGNoaWxkX3dyaXRlKGNz
X2FtYmlnX3dpZGUgPyAiXGVbMlciIDogIlxlWzFXIiwgNCk7CiAgICBlbHNl
CiAgICAgIGNoaWxkX3dyaXRlKCJcZVswVyIsIDQpOwogIGVsc2UgaWYgKHRl
cm0ucmVwb3J0X2FtYmlnX3dpZHRoICYmIG9sZF9hbWJpZ193aWRlICE9IGNz
X2FtYmlnX3dpZGUpCiAgICBjaGlsZF93cml0ZShjc19hbWJpZ193aWRlID8g
IlxlWzJXIiA6ICJcZVsxVyIsIDQpOwp9CgpzdGF0aWMgYm9vbApjb25maXJt
X2V4aXQodm9pZCkKewogIGlmICghY2hpbGRfaXNfcGFyZW50KCkpCiAgICBy
ZXR1cm4gdHJ1ZTsKCiAgLyogcmV0cmlldmUgbGlzdCBvZiBjaGlsZCBwcm9j
ZXNzZXMgKi8KICBjaGFyICogcHNjbWQgPSAicHJvY3BzIC1vIHBpZCxydXNl
cj1VU0VSIC1vIGNvbW0gLXQgJXMgMj4gL2Rldi9udWxsIHx8IHBzIC1lZiI7
CiAgY2hhciAqIHR0eSA9IGNoaWxkX3R0eSgpOwogIGlmIChzdHJyY2hyICh0
dHksICcvJykpCiAgICB0dHkgPSBzdHJyY2hyICh0dHksICcvJykgKyAxOwog
IGNoYXIgY21kW3N0cmxlbihwc2NtZCkgKyBzdHJsZW4odHR5KSArIDFdOwog
IHNwcmludGYgKGNtZCwgcHNjbWQsIHR0eSwgdHR5KTsKICBGSUxFICogcHJv
Y3BzID0gcG9wZW4gKGNtZCwgInIiKTsKICBjaGFyICogbXNnX3ByZSA9ICJQ
cm9jZXNzZXMgYXJlIHJ1bm5pbmcgaW4gc2Vzc2lvbjpcbiI7CiAgY2hhciAq
IG1zZ19wb3N0ID0gIkNsb3NlIGFueXdheT8iOwogIGNoYXIgKiBtc2cgPSBt
YWxsb2MgKHN0cmxlbiAobXNnX3ByZSkgKyAxKTsKICBzdHJjcHkgKG1zZywg
bXNnX3ByZSk7CiAgaWYgKHByb2NwcykgewogICAgY2hhciBsaW5lWzk5OV07
ICAvLyB1c2UgdmVyeSBsb25nIGlucHV0IGRlc3BpdGUgbmFycm93IG1zZyBi
b3gKICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYXZvaWQgaGlnaCByaXNr
IG9mIGNsaXBwaW5nIHdpdGhpbiBVVEYtOCAKICAgICAgICAgICAgICAgICAg
ICAgLy8gYW5kIGZhaWxpbmcgdGhlIHdpZGUgY2hhcmFjdGVyIHRyYW5zZm9y
bWF0aW9uCiAgICBib29sIGZpcnN0ID0gdHJ1ZTsKICAgIGJvb2wgZmlsdGVy
X3R0eSA9IGZhbHNlOwogICAgd2hpbGUgKGZnZXRzKGxpbmUsIHNpemVvZiBs
aW5lLCBwcm9jcHMpKSB7CiAgICAgIGxpbmVbc3RyY3NwbihsaW5lLCAiXHJc
biIpXSA9IDA7ICAvKiB0cmltIG5ld2xpbmUgKi8KICAgICAgaWYgKGZpcnN0
IHx8ICFmaWx0ZXJfdHR5IHx8IHN0cnN0ciAobGluZSwgdHR5KSkgIC8vIHNo
b3VsZCBjaGVjayBjb2x1bW4gcG9zaXRpb24gdG9vLi4uCiAgICAgIHsKICAg
ICAgICBpZiAoZmlyc3QpIHsKICAgICAgICAgIGlmIChzdHJzdHIgKGxpbmUs
ICJUVFkiKSkgewogICAgICAgICAgICBmaWx0ZXJfdHR5ID0gdHJ1ZTsKICAg
ICAgICAgIH0KICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgfQog
ICAgICAgIG1zZyA9IHJlYWxsb2MgKG1zZywgc3RybGVuIChtc2cpICsgc3Ry
bGVuIChsaW5lKSArIDIpOwogICAgICAgIHN0cmNhdCAobXNnLCBsaW5lKTsK
ICAgICAgICBzdHJjYXQgKG1zZywgIlxuIik7CiAgICAgIH0KICAgIH0KICAg
IGZjbG9zZShwcm9jcHMpOwogIH0KICBtc2cgPSByZWFsbG9jIChtc2csIHN0
cmxlbiAobXNnKSArIHN0cmxlbiAobXNnX3Bvc3QpICsgMSk7CiAgc3RyY2F0
IChtc2csIG1zZ19wb3N0KTsKCiAgc2l6ZV90IHNpemUgPSBjc19tYnN0b3dj
cygwLCBtc2csIDApICsgMTsKICBpbnQgcmV0OwogIGlmIChzaXplKSB7CiAg
ICB3Y2hhciBtc2d3W3NpemVdOwogICAgY3NfbWJzdG93Y3MobXNndywgbXNn
LCBzaXplKTsKICAgIHdjaGFyIGFwcG5bc3RybGVuKEFQUE5BTUUpICsgMV07
CiAgICBjc19tYnN0b3djcyhhcHBuLCBBUFBOQU1FLCBzaXplb2YgYXBwbik7
CiAgICByZXQgPQogICAgICBNZXNzYWdlQm94VygKICAgICAgICB3bmQsIG1z
Z3csCiAgICAgICAgYXBwbiwgTUJfSUNPTldBUk5JTkcgfCBNQl9PS0NBTkNF
TCB8IE1CX0RFRkJVVFRPTjIKICAgICAgKTsKICB9CiAgZWxzZSB7CiAgICBy
ZXQgPQogICAgICBNZXNzYWdlQm94KAogICAgICAgIHduZCwgbXNnLAogICAg
ICAgIEFQUE5BTUUsIE1CX0lDT05XQVJOSU5HIHwgTUJfT0tDQU5DRUwgfCBN
Ql9ERUZCVVRUT04yCiAgICAgICk7CiAgfQoKICAvLyBUcmVhdCBmYWlsdXJl
IHRvIHNob3cgdGhlIGRpYWxvZyBhcyBjb25maXJtYXRpb24uCiAgcmV0dXJu
ICFyZXQgfHwgcmV0ID09IElET0s7Cn0KCnN0YXRpYyBMUkVTVUxUIENBTExC
QUNLCndpbl9wcm9jKEhXTkQgd25kLCBVSU5UIG1lc3NhZ2UsIFdQQVJBTSB3
cCwgTFBBUkFNIGxwKQp7CiAgc3dpdGNoIChtZXNzYWdlKSB7CiAgICB3aGVu
IFdNX1RJTUVSOiB7CiAgICAgIEtpbGxUaW1lcih3bmQsIHdwKTsKICAgICAg
dm9pZF9mbiBjYiA9ICh2b2lkX2ZuKXdwOwogICAgICBjYigpOwogICAgICBy
ZXR1cm4gMDsKICAgIH0KICAgIHdoZW4gV01fQ0xPU0U6CiAgICAgIGlmICgh
Y2ZnLmNvbmZpcm1fZXhpdCB8fCBjb25maXJtX2V4aXQoKSkKICAgICAgICBj
aGlsZF9raWxsKChHZXRLZXlTdGF0ZShWS19TSElGVCkgJiAweDgwKSAhPSAw
KTsKICAgICAgcmV0dXJuIDA7CiAgICB3aGVuIFdNX0NPTU1BTkQgb3IgV01f
U1lTQ09NTUFORDoKICAgICAgc3dpdGNoICh3cCAmIH4weEYpIHsgIC8qIGxv
dyA0IGJpdHMgcmVzZXJ2ZWQgdG8gV2luZG93cyAqLwogICAgICAgIHdoZW4g
SURNX09QRU46IHRlcm1fb3BlbigpOwogICAgICAgIHdoZW4gSURNX0NPUFk6
IHRlcm1fY29weSgpOwogICAgICAgIHdoZW4gSURNX1BBU1RFOiB3aW5fcGFz
dGUoKTsKICAgICAgICB3aGVuIElETV9TRUxBTEw6IHRlcm1fc2VsZWN0X2Fs
bCgpOyB3aW5fdXBkYXRlKCk7CiAgICAgICAgd2hlbiBJRE1fUkVTRVQ6IHRl
cm1fcmVzZXQoKTsgd2luX3VwZGF0ZSgpOwogICAgICAgIHdoZW4gSURNX0RF
RlNJWkU6IGRlZmF1bHRfc2l6ZSgpOwogICAgICAgIHdoZW4gSURNX0ZVTExT
Q1JFRU46IHdpbl9tYXhpbWlzZSh3aW5faXNfZnVsbHNjcmVlbiA/IDAgOiAy
KTsKICAgICAgICB3aGVuIElETV9GTElQU0NSRUVOOiB0ZXJtX2ZsaXBfc2Ny
ZWVuKCk7CiAgICAgICAgd2hlbiBJRE1fT1BUSU9OUzogd2luX29wZW5fY29u
ZmlnKCk7CiAgICAgICAgd2hlbiBJRE1fTkVXOiBjaGlsZF9mb3JrKG1haW5f
YXJnYywgbWFpbl9hcmd2KTsKICAgICAgICB3aGVuIElETV9DT1BZVElUTEU6
IHdpbl9jb3B5X3RpdGxlKCk7CiAgICAgIH0KICAgIHdoZW4gV01fVlNDUk9M
TDoKICAgICAgc3dpdGNoIChMT1dPUkQod3ApKSB7CiAgICAgICAgd2hlbiBT
Ql9CT1RUT006ICAgdGVybV9zY3JvbGwoLTEsIDApOwogICAgICAgIHdoZW4g
U0JfVE9QOiAgICAgIHRlcm1fc2Nyb2xsKCsxLCAwKTsKICAgICAgICB3aGVu
IFNCX0xJTkVET1dOOiB0ZXJtX3Njcm9sbCgwLCArMSk7CiAgICAgICAgd2hl
biBTQl9MSU5FVVA6ICAgdGVybV9zY3JvbGwoMCwgLTEpOwogICAgICAgIHdo
ZW4gU0JfUEFHRURPV046IHRlcm1fc2Nyb2xsKDAsICttYXgoMSwgdGVybS5y
b3dzIC0gMSkpOwogICAgICAgIHdoZW4gU0JfUEFHRVVQOiAgIHRlcm1fc2Ny
b2xsKDAsIC1tYXgoMSwgdGVybS5yb3dzIC0gMSkpOwogICAgICAgIHdoZW4g
U0JfVEhVTUJQT1NJVElPTiBvciBTQl9USFVNQlRSQUNLOiB7CiAgICAgICAg
ICBTQ1JPTExJTkZPIGluZm87CiAgICAgICAgICBpbmZvLmNiU2l6ZSA9IHNp
emVvZihTQ1JPTExJTkZPKTsKICAgICAgICAgIGluZm8uZk1hc2sgPSBTSUZf
VFJBQ0tQT1M7CiAgICAgICAgICBHZXRTY3JvbGxJbmZvKHduZCwgU0JfVkVS
VCwgJmluZm8pOwogICAgICAgICAgdGVybV9zY3JvbGwoMSwgaW5mby5uVHJh
Y2tQb3MpOwogICAgICAgIH0KICAgICAgfQogICAgd2hlbiBXTV9MQlVUVE9O
RE9XTjogd2luX21vdXNlX2NsaWNrKE1CVF9MRUZULCBscCk7CiAgICB3aGVu
IFdNX1JCVVRUT05ET1dOOiB3aW5fbW91c2VfY2xpY2soTUJUX1JJR0hULCBs
cCk7CiAgICB3aGVuIFdNX01CVVRUT05ET1dOOiB3aW5fbW91c2VfY2xpY2so
TUJUX01JRERMRSwgbHApOwogICAgd2hlbiBXTV9MQlVUVE9OVVA6IHdpbl9t
b3VzZV9yZWxlYXNlKE1CVF9MRUZULCBscCk7CiAgICB3aGVuIFdNX1JCVVRU
T05VUDogd2luX21vdXNlX3JlbGVhc2UoTUJUX1JJR0hULCBscCk7CiAgICB3
aGVuIFdNX01CVVRUT05VUDogd2luX21vdXNlX3JlbGVhc2UoTUJUX01JRERM
RSwgbHApOwogICAgd2hlbiBXTV9NT1VTRU1PVkU6IHdpbl9tb3VzZV9tb3Zl
KGZhbHNlLCBscCk7CiAgICB3aGVuIFdNX05DTU9VU0VNT1ZFOiB3aW5fbW91
c2VfbW92ZSh0cnVlLCBscCk7CiAgICB3aGVuIFdNX01PVVNFV0hFRUw6IHdp
bl9tb3VzZV93aGVlbCh3cCwgbHApOwogICAgd2hlbiBXTV9LRVlET1dOIG9y
IFdNX1NZU0tFWURPV046CiAgICAgIGlmICh3aW5fa2V5X2Rvd24od3AsIGxw
KSkKICAgICAgICByZXR1cm4gMDsKICAgIHdoZW4gV01fS0VZVVAgb3IgV01f
U1lTS0VZVVA6CiAgICAgIGlmICh3aW5fa2V5X3VwKHdwLCBscCkpCiAgICAg
ICAgcmV0dXJuIDA7CiAgICB3aGVuIFdNX0NIQVIgb3IgV01fU1lTQ0hBUjoK
ICAgICAgY2hpbGRfc2VuZHcoJih3Y2hhcil7d3B9LCAxKTsKICAgICAgcmV0
dXJuIDA7CiAgICB3aGVuIFdNX0lOUFVUTEFOR0NIQU5HRToKICAgICAgd2lu
X3NldF9pbWVfb3BlbihJbW1Jc0lNRShHZXRLZXlib2FyZExheW91dCgwKSkg
JiYgSW1tR2V0T3BlblN0YXR1cyhpbWMpKTsKICAgIHdoZW4gV01fSU1FX05P
VElGWToKICAgICAgaWYgKHdwID09IElNTl9TRVRPUEVOU1RBVFVTKQogICAg
ICAgIHdpbl9zZXRfaW1lX29wZW4oSW1tR2V0T3BlblN0YXR1cyhpbWMpKTsK
ICAgIHdoZW4gV01fSU1FX1NUQVJUQ09NUE9TSVRJT046CiAgICAgIEltbVNl
dENvbXBvc2l0aW9uRm9udChpbWMsICZsZm9udCk7CiAgICB3aGVuIFdNX0lN
RV9DT01QT1NJVElPTjoKICAgICAgaWYgKGxwICYgR0NTX1JFU1VMVFNUUikg
ewogICAgICAgIExPTkcgbGVuID0gSW1tR2V0Q29tcG9zaXRpb25TdHJpbmdX
KGltYywgR0NTX1JFU1VMVFNUUiwgbnVsbCwgMCk7CiAgICAgICAgaWYgKGxl
biA+IDApIHsKICAgICAgICAgIGNoYXIgYnVmW2xlbl07CiAgICAgICAgICBJ
bW1HZXRDb21wb3NpdGlvblN0cmluZ1coaW1jLCBHQ1NfUkVTVUxUU1RSLCBi
dWYsIGxlbik7CiAgICAgICAgICBjaGlsZF9zZW5kdygod2NoYXIgKilidWYs
IGxlbiAvIDIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMTsKICAgICAg
fQogICAgd2hlbiBXTV9QQUlOVDoKICAgICAgd2luX3BhaW50KCk7CiAgICAg
IHJldHVybiAwOwogICAgd2hlbiBXTV9TRVRGT0NVUzoKICAgICAgdGVybV9z
ZXRfZm9jdXModHJ1ZSk7CiAgICAgIENyZWF0ZUNhcmV0KHduZCwgY2FyZXRi
bSwgMCwgMCk7CiAgICAgIGZsYXNoX3Rhc2tiYXIoZmFsc2UpOyAgLyogc3Rv
cCAqLwogICAgICB3aW5fdXBkYXRlKCk7CiAgICAgIHVwZGF0ZV90cmFuc3Bh
cmVuY3koKTsKICAgICAgU2hvd0NhcmV0KHduZCk7CiAgICB3aGVuIFdNX0tJ
TExGT0NVUzoKICAgICAgd2luX3Nob3dfbW91c2UoKTsKICAgICAgdGVybV9z
ZXRfZm9jdXMoZmFsc2UpOwogICAgICBEZXN0cm95Q2FyZXQoKTsKICAgICAg
d2luX3VwZGF0ZSgpOwogICAgICB1cGRhdGVfdHJhbnNwYXJlbmN5KCk7CiAg
ICB3aGVuIFdNX0VOVEVSU0laRU1PVkU6CiAgICAgIHRyYWNlX3Jlc2l6ZSgo
Ii0tLSBXTV9FTlRFUlNJWkVNT1ZFIFZLX1NISUZUICUwMlhcbiIsIEdldEtl
eVN0YXRlKFZLX1NISUZUKSkpOwogICAgICByZXNpemluZyA9IHRydWU7CiAg
ICB3aGVuIFdNX0VYSVRTSVpFTU9WRSBvciBXTV9DQVBUVVJFQ0hBTkdFRDog
IC8vIGFmdGVyIG1vdXNlLWRyYWcgcmVzaXppbmcKICAgICAgdHJhY2VfcmVz
aXplKCgiLS0tIFdNX0VYSVRTSVpFTU9WRSAocmVzaXppbmcgJWQpIFZLX1NI
SUZUICUwMlhcbiIsIHJlc2l6aW5nLCBHZXRLZXlTdGF0ZShWS19TSElGVCkp
KTsKICAgICAgaWYgKHJlc2l6aW5nKSB7CiAgICAgICAgcmVzaXppbmcgPSBm
YWxzZTsKICAgICAgICB3aW5fZGVzdHJveV90aXAoKTsKICAgICAgICB0cmFj
ZV9yZXNpemUoKCIgKHdpbl9wcm9jIC0+IHdpbl9hZGFwdF90ZXJtX3NpemUp
XG4iKSk7CiAgICAgICAgd2luX2FkYXB0X3Rlcm1fc2l6ZShHZXRLZXlTdGF0
ZShWS19TSElGVCkgJiAweDgwLCBmYWxzZSk7CiAgICAgIH0KICAgIHdoZW4g
V01fU0laSU5HOiB7ICAvLyBtb3VzZS1kcmFnIHdpbmRvdyByZXNpemluZwog
ICAgICB0cmFjZV9yZXNpemUoKCItLS0gV01fU0laSU5HIChyZXNpemluZyAl
ZCkgVktfU0hJRlQgJTAyWFxuIiwgcmVzaXppbmcsIEdldEtleVN0YXRlKFZL
X1NISUZUKSkpOwogICAgIC8qCiAgICAgICogVGhpcyBkb2VzIHR3byBqb2Jz
OgogICAgICAqIDEpIEtlZXAgdGhlIHRpcCB1cHRvZGF0ZQogICAgICAqIDIp
IE1ha2Ugc3VyZSB0aGUgd2luZG93IHNpemUgaXMgX3N0ZXBwZWRfIGluIHVu
aXRzIG9mIHRoZSBmb250IHNpemUuCiAgICAgICovCiAgICAgIExQUkVDVCBy
ID0gKExQUkVDVCkgbHA7CiAgICAgIGludCB3aWR0aCA9IHItPnJpZ2h0IC0g
ci0+bGVmdCAtIGV4dHJhX3dpZHRoIC0gMiAqIFBBRERJTkc7CiAgICAgIGlu
dCBoZWlnaHQgPSByLT5ib3R0b20gLSByLT50b3AgLSBleHRyYV9oZWlnaHQg
LSAyICogUEFERElORzsKICAgICAgaW50IGNvbHMgPSBtYXgoMSwgKGZsb2F0
KXdpZHRoIC8gZm9udF93aWR0aCArIDAuNSk7CiAgICAgIGludCByb3dzID0g
bWF4KDEsIChmbG9hdCloZWlnaHQgLyBmb250X2hlaWdodCArIDAuNSk7Cgog
ICAgICBpbnQgZXcgPSB3aWR0aCAtIGNvbHMgKiBmb250X3dpZHRoOwogICAg
ICBpbnQgZWggPSBoZWlnaHQgLSByb3dzICogZm9udF9oZWlnaHQ7CgogICAg
ICBpZiAod3AgPj0gV01TWl9CT1RUT00pIHsKICAgICAgICB3cCAtPSBXTVNa
X0JPVFRPTTsKICAgICAgICByLT5ib3R0b20gLT0gZWg7CiAgICAgIH0KICAg
ICAgZWxzZSBpZiAod3AgPj0gV01TWl9UT1ApIHsKICAgICAgICB3cCAtPSBX
TVNaX1RPUDsKICAgICAgICByLT50b3AgKz0gZWg7CiAgICAgIH0KCiAgICAg
IGlmICh3cCA9PSBXTVNaX1JJR0hUKQogICAgICAgIHItPnJpZ2h0IC09IGV3
OwogICAgICBlbHNlIGlmICh3cCA9PSBXTVNaX0xFRlQpCiAgICAgICAgci0+
bGVmdCArPSBldzsKCiAgICAgIHdpbl9zaG93X3RpcChyLT5sZWZ0ICsgZXh0
cmFfd2lkdGgsIHItPnRvcCArIGV4dHJhX2hlaWdodCwgY29scywgcm93cyk7
CgogICAgICByZXR1cm4gZXcgfHwgZWg7CiAgICB9CiAgICB3aGVuIFdNX1NJ
WkU6IHsKICAgICAgdHJhY2VfcmVzaXplKCgiLS0tIFdNX1NJWkUgKHJlc2l6
aW5nICVkKSBWS19TSElGVCAlMDJYXG4iLCByZXNpemluZywgR2V0S2V5U3Rh
dGUoVktfU0hJRlQpKSk7CiAgICAgIGlmICh3cCA9PSBTSVpFX1JFU1RPUkVE
ICYmIHdpbl9pc19mdWxsc2NyZWVuKQogICAgICAgIGNsZWFyX2Z1bGxzY3Jl
ZW4oKTsKICAgICAgZWxzZSBpZiAod3AgPT0gU0laRV9NQVhJTUlaRUQgJiYg
ZnVsbHNjcl9vbl9tYXgpIHsKICAgICAgICBmdWxsc2NyX29uX21heCA9IGZh
bHNlOwogICAgICAgIG1ha2VfZnVsbHNjcmVlbigpOwogICAgICB9CgogICAg
ICBpZiAoIXJlc2l6aW5nKSB7CiAgICAgICAgdHJhY2VfcmVzaXplKCgiICh3
aW5fcHJvYyAtPiB3aW5fYWRhcHRfdGVybV9zaXplKVxuIikpOwogICAgICAg
IHdpbl9hZGFwdF90ZXJtX3NpemUoZmFsc2UsIEdldEtleVN0YXRlKFZLX1NI
SUZUKSAmIDB4ODApOwogICAgICB9CgogICAgICByZXR1cm4gMDsKICAgIH0K
ICAgIHdoZW4gV01fSU5JVE1FTlU6CiAgICAgIHdpbl91cGRhdGVfbWVudXMo
KTsKICAgICAgcmV0dXJuIDA7CiAgfQogLyoKICAqIEFueSBtZXNzYWdlcyB3
ZSBkb24ndCBwcm9jZXNzIGNvbXBsZXRlbHkgYWJvdmUgYXJlIHBhc3NlZCB0
aHJvdWdoIHRvCiAgKiBEZWZXaW5kb3dQcm9jKCkgZm9yIGRlZmF1bHQgcHJv
Y2Vzc2luZy4KICAqLwogIHJldHVybiBEZWZXaW5kb3dQcm9jVyh3bmQsIG1l
c3NhZ2UsIHdwLCBscCk7Cn0KCnN0YXRpYyBjb25zdCBjaGFyIGhlbHBbXSA9
CiAgIlVzYWdlOiAiIEFQUE5BTUUgIiBbT1BUSU9OXS4uLiBbIFBST0dSQU0g
W0FSR10uLi4gfCAtIF1cbiIKICAiXG4iCiAgIlN0YXJ0IGEgbmV3IHRlcm1p
bmFsIHNlc3Npb24gcnVubmluZyB0aGUgc3BlY2lmaWVkIHByb2dyYW0gb3Ig
dGhlIHVzZXIncyBzaGVsbC5cbiIKICAiSWYgYSBkYXNoIGlzIGdpdmVuIGlu
c3RlYWQgb2YgYSBwcm9ncmFtLCBpbnZva2UgdGhlIHNoZWxsIGFzIGEgbG9n
aW4gc2hlbGwuXG4iCiAgIlxuIgogICJPcHRpb25zOlxuIgogICIgIC1jLCAt
LWNvbmZpZyBGSUxFICAgICBMb2FkIHNwZWNpZmllZCBjb25maWcgZmlsZVxu
IgogICIgIC1lLCAtLWV4ZWMgICAgICAgICAgICBUcmVhdCByZW1haW5pbmcg
YXJndW1lbnRzIGFzIHRoZSBjb21tYW5kIHRvIGV4ZWN1dGVcbiIKICAiICAt
aCwgLS1ob2xkIG5ldmVyfHN0YXJ0fGVycm9yfGFsd2F5cyAgS2VlcCB3aW5k
b3cgb3BlbiBhZnRlciBjb21tYW5kIGZpbmlzaGVzXG4iCiAgIiAgLWksIC0t
aWNvbiBGSUxFWyxJWF0gIExvYWQgd2luZG93IGljb24gZnJvbSBmaWxlLCBv
cHRpb25hbGx5IHdpdGggaW5kZXhcbiIKICAiICAtbCwgLS1sb2cgRklMRXwt
ICAgICAgTG9nIG91dHB1dCB0byBmaWxlIG9yIHN0ZG91dFxuIgogICIgIC1v
LCAtLW9wdGlvbiBPUFQ9VkFMICBPdmVycmlkZSBjb25maWcgZmlsZSBvcHRp
b24gd2l0aCBnaXZlbiB2YWx1ZVxuIgogICIgIC1wLCAtLXBvc2l0aW9uIFgs
WSAgICBPcGVuIHdpbmRvdyBhdCBzcGVjaWZpZWQgY29vcmRpbmF0ZXNcbiIK
ICAiICAtcywgLS1zaXplIENPTFMsUk9XUyAgU2V0IHNjcmVlbiBzaXplIGlu
IGNoYXJhY3RlcnNcbiIKICAiICAtdCwgLS10aXRsZSBUSVRMRSAgICAgU2V0
IHdpbmRvdyB0aXRsZSAoZGVmYXVsdDogdGhlIGludm9rZWQgY29tbWFuZClc
biIKICAiICAtdSwgLS11dG1wICAgICAgICAgICAgQ3JlYXRlIGEgdXRtcCBl
bnRyeVxuIgogICIgIC13LCAtLXdpbmRvdyBub3JtYWx8bWlufG1heHxmdWxs
fGhpZGUgIFNldCBpbml0aWFsIHdpbmRvdyBzdGF0ZVxuIgogICIgICAgICAt
LWNsYXNzIENMQVNTICAgICBTZXQgd2luZG93IGNsYXNzIG5hbWUgKGRlZmF1
bHQ6ICIgQVBQTkFNRSAiKVxuIgogICIgIC1ILCAtLWhlbHAgICAgICAgICAg
ICBEaXNwbGF5IGhlbHAgYW5kIGV4aXRcbiIKICAiICAtViwgLS12ZXJzaW9u
ICAgICAgICAgUHJpbnQgdmVyc2lvbiBpbmZvcm1hdGlvbiBhbmQgZXhpdFxu
Igo7CgpzdGF0aWMgY29uc3QgY2hhciBzaG9ydF9vcHRzW10gPSAiKzpjOmVo
Omk6bDpvOnA6czp0OlQ6Qjp1dzpIVjpEIjsKCnN0YXRpYyBjb25zdCBzdHJ1
Y3Qgb3B0aW9uCm9wdHNbXSA9IHsKICB7ImNvbmZpZyIsICAgcmVxdWlyZWRf
YXJndW1lbnQsIDAsICdjJ30sCiAgeyJleGVjIiwgICAgIG5vX2FyZ3VtZW50
LCAgICAgICAwLCAnZSd9LAogIHsiaG9sZCIsICAgICByZXF1aXJlZF9hcmd1
bWVudCwgMCwgJ2gnfSwKICB7Imljb24iLCAgICAgcmVxdWlyZWRfYXJndW1l
bnQsIDAsICdpJ30sCiAgeyJsb2ciLCAgICAgIHJlcXVpcmVkX2FyZ3VtZW50
LCAwLCAnbCd9LAogIHsidXRtcCIsICAgICBub19hcmd1bWVudCwgICAgICAg
MCwgJ3UnfSwKICB7Im9wdGlvbiIsICAgcmVxdWlyZWRfYXJndW1lbnQsIDAs
ICdvJ30sCiAgeyJwb3NpdGlvbiIsIHJlcXVpcmVkX2FyZ3VtZW50LCAwLCAn
cCd9LAogIHsic2l6ZSIsICAgICByZXF1aXJlZF9hcmd1bWVudCwgMCwgJ3Mn
fSwKICB7InRpdGxlIiwgICAgcmVxdWlyZWRfYXJndW1lbnQsIDAsICd0J30s
CiAgeyJUaXRsZSIsICAgIHJlcXVpcmVkX2FyZ3VtZW50LCAwLCAnVCd9LAog
IHsiQm9yZGVyIiwgICByZXF1aXJlZF9hcmd1bWVudCwgMCwgJ0InfSwKICB7
IndpbmRvdyIsICAgcmVxdWlyZWRfYXJndW1lbnQsIDAsICd3J30sCiAgeyJj
bGFzcyIsICAgIHJlcXVpcmVkX2FyZ3VtZW50LCAwLCAnQyd9LAogIHsiaGVs
cCIsICAgICBub19hcmd1bWVudCwgICAgICAgMCwgJ0gnfSwKICB7InZlcnNp
b24iLCAgbm9fYXJndW1lbnQsICAgICAgIDAsICdWJ30sCiAgeyJkYWVtb24i
LCAgIG5vX2FyZ3VtZW50LCAgICAgICAwLCAnRCd9LAogIHswLCAwLCAwLCAw
fQp9OwoKc3RhdGljIHZvaWQKc2hvd19tc2coRklMRSAqc3RyZWFtLCBzdHJp
bmcgbXNnKQp7CiAgaWYgKGZwdXRzKG1zZywgc3RyZWFtKSA8IDAgfHwgZmZs
dXNoKHN0cmVhbSkgPCAwKQogICAgTWVzc2FnZUJveCgwLCBtc2csIEFQUE5B
TUUsIE1CX09LKTsKfQoKc3RhdGljIG5vX3JldHVybiBfX2F0dHJpYnV0ZV9f
KChmb3JtYXQocHJpbnRmLCAxLCAyKSkpCmVycm9yKGNoYXIgKmZvcm1hdCwg
Li4uKQp7CiAgY2hhciAqbXNnOwogIHZhX2xpc3QgdmE7CiAgdmFfc3RhcnQo
dmEsIGZvcm1hdCk7CiAgdmFzcHJpbnRmKCZtc2csIGZvcm1hdCwgdmEpOwog
IHZhX2VuZCh2YSk7CiAgbXNnID0gYXNmb3JtKCIlczogJXNcblRyeSAnLS1o
ZWxwJyBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiIsCiAgICAgICAgICAgICAg
IG1haW5fYXJndlswXSwgbXNnKTsKICBzaG93X21zZyhzdGRlcnIsIG1zZyk7
CiAgZXhpdCgxKTsKfQoKc3RhdGljIHZvaWQgX19hdHRyaWJ1dGVfXygoZm9y
bWF0KHByaW50ZiwgMSwgMikpKQp3YXJuKGNoYXIgKmZvcm1hdCwgLi4uKQp7
CiAgY2hhciAqbXNnOwogIHZhX2xpc3QgdmE7CiAgdmFfc3RhcnQodmEsIGZv
cm1hdCk7CiAgdmFzcHJpbnRmKCZtc2csIGZvcm1hdCwgdmEpOwogIHZhX2Vu
ZCh2YSk7CiAgbXNnID0gYXNmb3JtKCIlczogJXNcbiIsIG1haW5fYXJndlsw
XSwgbXNnKTsKICBzaG93X21zZyhzdGRlcnIsIG1zZyk7Cn0KCmludAptYWlu
KGludCBhcmdjLCBjaGFyICphcmd2W10pCnsKICBtYWluX2FyZ3YgPSBhcmd2
OwogIG1haW5fYXJnYyA9IGFyZ2M7CiAgbG9hZF9kd21fZnVuY3MoKTsKICBp
bml0X2NvbmZpZygpOwogIGNzX2luaXQoKTsKCiAgLy8gRGV0ZXJtaW5lIGhv
bWUgZGlyZWN0b3J5LgogIGhvbWUgPSBnZXRlbnYoIkhPTUUiKTsKI2lmIENZ
R1dJTl9WRVJTSU9OX0RMTF9NQUpPUiA+PSAxMDA1CiAgLy8gQmVmb3JlIEN5
Z3dpbiAxLjUsIHRoZSBwYXNzd2Qgc3RydWN0dXJlIGlzIGZha2VkLgogIHN0
cnVjdCBwYXNzd2QgKnB3ID0gZ2V0cHd1aWQoZ2V0dWlkKCkpOwojZW5kaWYK
ICBob21lID0gaG9tZSA/IHN0cmR1cChob21lKSA6CiNpZiBDWUdXSU5fVkVS
U0lPTl9ETExfTUFKT1IgPj0gMTAwNQogICAgKHB3ICYmIHB3LT5wd19kaXIg
JiYgKnB3LT5wd19kaXIpID8gc3RyZHVwKHB3LT5wd19kaXIpIDoKI2VuZGlm
CiAgICBhc2Zvcm0oIi9ob21lLyVzIiwgZ2V0bG9naW4oKSk7CgogIC8vIFNl
dCBzaXplIGFuZCBwb3NpdGlvbiBkZWZhdWx0cy4KICBTVEFSVFVQSU5GTyBz
dWk7CiAgR2V0U3RhcnR1cEluZm8oJnN1aSk7CiAgY2ZnLndpbmRvdyA9IHN1
aS5kd0ZsYWdzICYgU1RBUlRGX1VTRVNIT1dXSU5ET1cgPyBzdWkud1Nob3dX
aW5kb3cgOiBTV19TSE9XOwogIGNmZy54ID0gY2ZnLnkgPSBDV19VU0VERUZB
VUxUOwoKICBsb2FkX2NvbmZpZygiL2V0Yy9taW50dHlyYyIpOwogIHN0cmlu
ZyByY19maWxlID0gYXNmb3JtKCIlcy8ubWludHR5cmMiLCBob21lKTsKICBs
b2FkX2NvbmZpZyhyY19maWxlKTsKICBkZWxldGUocmNfZmlsZSk7CgogIGlm
IChnZXRlbnYoIk1JTlRUWV9ST1dTIikpIHsKICAgIHNldF9hcmdfb3B0aW9u
KCJSb3dzIiwgZ2V0ZW52KCJNSU5UVFlfUk9XUyIpKTsKICB9CiAgaWYgKGdl
dGVudigiTUlOVFRZX0NPTFMiKSkgewogICAgc2V0X2FyZ19vcHRpb24oIkNv
bHVtbnMiLCBnZXRlbnYoIk1JTlRUWV9DT0xTIikpOwogIH0KCiAgZm9yICg7
OykgewogICAgaW50IG9wdCA9IGdldG9wdF9sb25nKGFyZ2MsIGFyZ3YsIHNo
b3J0X29wdHMsIG9wdHMsIDApOwogICAgaWYgKG9wdCA9PSAtMSB8fCBvcHQg
PT0gJ2UnKQogICAgICBicmVhazsKICAgIGNoYXIgKmxvbmdvcHQgPSBhcmd2
W29wdGluZCAtIDFdLCAqc2hvcnRvcHQgPSAoY2hhcltdKXsnLScsIG9wdG9w
dCwgMH07CiAgICBzd2l0Y2ggKG9wdCkgewogICAgICB3aGVuICdjJzogbG9h
ZF9jb25maWcob3B0YXJnKTsKICAgICAgd2hlbiAnaCc6IHNldF9hcmdfb3B0
aW9uKCJIb2xkIiwgb3B0YXJnKTsKICAgICAgd2hlbiAnaSc6IHNldF9hcmdf
b3B0aW9uKCJJY29uIiwgb3B0YXJnKTsKICAgICAgd2hlbiAnbCc6IHNldF9h
cmdfb3B0aW9uKCJMb2ciLCBvcHRhcmcpOwogICAgICB3aGVuICdvJzogcGFy
c2VfYXJnX29wdGlvbihvcHRhcmcpOwogICAgICB3aGVuICdwJzoKICAgICAg
ICBpZiAoc3NjYW5mKG9wdGFyZywgIiVpLCVpJTFzIiwgJmNmZy54LCAmY2Zn
LnksIChjaGFyWzJdKXt9KSAhPSAyKQogICAgICAgICAgZXJyb3IoInN5bnRh
eCBlcnJvciBpbiBwb3NpdGlvbiBhcmd1bWVudCAnJXMnIiwgb3B0YXJnKTsK
ICAgICAgd2hlbiAncyc6CiAgICAgICAgaWYgKHNzY2FuZihvcHRhcmcsICIl
dSwldSUxcyIsICZjZmcuY29scywgJmNmZy5yb3dzLCAoY2hhclsyXSl7fSkg
IT0gMikKICAgICAgICAgIGVycm9yKCJzeW50YXggZXJyb3IgaW4gc2l6ZSBh
cmd1bWVudCAnJXMnIiwgb3B0YXJnKTsKICAgICAgICByZW1lbWJlcl9hcmco
IkNvbHVtbnMiKTsKICAgICAgICByZW1lbWJlcl9hcmcoIlJvd3MiKTsKICAg
ICAgd2hlbiAndCc6IHNldF9hcmdfb3B0aW9uKCJUaXRsZSIsIG9wdGFyZyk7
CiAgICAgIHdoZW4gJ1QnOgogICAgICAgIHNldF9hcmdfb3B0aW9uKCJUaXRs
ZSIsIG9wdGFyZyk7CiAgICAgICAgdGl0bGVfc2V0dGFibGUgPSBmYWxzZTsK
ICAgICAgd2hlbiAnQic6CiAgICAgICAgYm9yZGVyX3N0eWxlID0gc3RyZHVw
IChvcHRhcmcpOwogICAgICB3aGVuICd1JzogY2ZnLnV0bXAgPSB0cnVlOwog
ICAgICB3aGVuICd3Jzogc2V0X2FyZ19vcHRpb24oIldpbmRvdyIsIG9wdGFy
Zyk7CiAgICAgIHdoZW4gJ0MnOiBzZXRfYXJnX29wdGlvbigiQ2xhc3MiLCBv
cHRhcmcpOwogICAgICB3aGVuICdEJzoKICAgICAgICBkYWVtb25pemUgPSB0
cnVlOwogICAgICB3aGVuICdIJzoKICAgICAgICBzaG93X21zZyhzdGRvdXQs
IGhlbHApOwogICAgICAgIHJldHVybiAwOwogICAgICB3aGVuICdWJzoKICAg
ICAgICBzaG93X21zZyhzdGRvdXQsIFZFUlNJT05fVEVYVCk7CiAgICAgICAg
cmV0dXJuIDA7CiAgICAgIHdoZW4gJz8nOgogICAgICAgIGVycm9yKCJ1bmtu
b3duIG9wdGlvbiAnJXMnIiwgb3B0b3B0ID8gc2hvcnRvcHQgOiBsb25nb3B0
KTsKICAgICAgd2hlbiAnOic6CiAgICAgICAgZXJyb3IoIm9wdGlvbiAnJXMn
IHJlcXVpcmVzIGFuIGFyZ3VtZW50IiwKICAgICAgICAgICAgICBsb25nb3B0
WzFdID09ICctJyA/IGxvbmdvcHQgOiBzaG9ydG9wdCk7CiAgICB9CiAgfQoK
ICBmaW5pc2hfY29uZmlnKCk7CgogIC8vIGlmIHN0YXJ0ZWQgZnJvbSBjb25z
b2xlLCB0cnkgdG8gZGV0YWNoIGZyb20gY2FsbGVyJ3MgdGVybWluYWwgKH5k
YWVtb25pemUpCiAgLy8gaW4gb3JkZXIgdG8gbm90IHN1cHByZXNzIHNpZ25h
bHMKICAvLyAoaW5kaWNhdGVkIGJ5IGlzYXR0eSBpZiBsaW5rZWQgd2l0aCAt
bXdpbmRvd3MpCiAgaWYgKGRhZW1vbml6ZSAmJiAhaXNhdHR5KDApKSB7CiAg
ICBpZiAoZm9yaygpID4gMCkgZXhpdCgwKTsKICAgIHNldHNpZCgpOwogIH0K
CiAgLy8gV29yayBvdXQgd2hhdCB0byBleGVjdXRlLgogIGFyZ3YgKz0gb3B0
aW5kOwogIGlmICgqYXJndiAmJiAoYXJndlsxXSB8fCBzdHJjbXAoKmFyZ3Ys
ICItIikpKQogICAgY21kID0gKmFyZ3Y7CiAgZWxzZSB7CiAgICAvLyBMb29r
IHVwIHRoZSB1c2VyJ3Mgc2hlbGwuCiAgICBjbWQgPSBnZXRlbnYoIlNIRUxM
Iik7CiAgICBjbWQgPSBjbWQgPyBzdHJkdXAoY21kKSA6CiNpZiBDWUdXSU5f
VkVSU0lPTl9ETExfTUFKT1IgPj0gMTAwNQogICAgICAocHcgJiYgcHctPnB3
X3NoZWxsICYmICpwdy0+cHdfc2hlbGwpID8gc3RyZHVwKHB3LT5wd19zaGVs
bCkgOgojZW5kaWYKICAgICAgIi9iaW4vc2giOwoKICAgIC8vIERldGVybWlu
ZSB0aGUgcHJvZ3JhbSBuYW1lIGFyZ3VtZW50LgogICAgY2hhciAqc2xhc2gg
PSBzdHJyY2hyKGNtZCwgJy8nKTsKICAgIGNoYXIgKmFyZzAgPSBzbGFzaCA/
IHNsYXNoICsgMSA6IGNtZDsKCiAgICAvLyBQcmVwZW5kICctJyBpZiBhIGxv
Z2luIHNoZWxsIHdhcyByZXF1ZXN0ZWQuCiAgICBpZiAoKmFyZ3YpCiAgICAg
IGFyZzAgPSBhc2Zvcm0oIi0lcyIsIGFyZzApOwoKICAgIC8vIENyZWF0ZSBu
ZXcgYXJndW1lbnQgYXJyYXkuCiAgICBhcmd2ID0gbmV3bihjaGFyICosIDIp
OwogICAgKmFyZ3YgPSBhcmcwOwogIH0KCiAgLy8gTG9hZCBpY29uIGlmIHNw
ZWNpZmllZC4KICBISUNPTiBsYXJnZV9pY29uID0gMCwgc21hbGxfaWNvbiA9
IDA7CiAgaWYgKCpjZmcuaWNvbikgewogICAgc3RyaW5nIGljb25fZmlsZSA9
IHN0cmR1cChjZmcuaWNvbik7CiAgICB1aW50IGljb25faW5kZXggPSAwOwog
ICAgY2hhciAqY29tbWEgPSBzdHJyY2hyKGljb25fZmlsZSwgJywnKTsKICAg
IGlmIChjb21tYSkgewogICAgICBjaGFyICpzdGFydCA9IGNvbW1hICsgMSwg
KmVuZDsKICAgICAgaWNvbl9pbmRleCA9IHN0cnRvdWwoc3RhcnQsICZlbmQs
IDApOwogICAgICBpZiAoc3RhcnQgIT0gZW5kICYmICEqZW5kKQogICAgICAg
ICpjb21tYSA9IDA7CiAgICAgIGVsc2UKICAgICAgICBpY29uX2luZGV4ID0g
MDsKICAgIH0KICAgIFNldExhc3RFcnJvcigwKTsKI2lmIENZR1dJTl9WRVJT
SU9OX0FQSV9NSU5PUiA+PSAxODEKICAgIHdjaGFyICp3aW5faWNvbl9maWxl
ID0gY3lnd2luX2NyZWF0ZV9wYXRoKENDUF9QT1NJWF9UT19XSU5fVywgaWNv
bl9maWxlKTsKICAgIGlmICh3aW5faWNvbl9maWxlKSB7CiAgICAgIEV4dHJh
Y3RJY29uRXhXKHdpbl9pY29uX2ZpbGUsIGljb25faW5kZXgsICZsYXJnZV9p
Y29uLCAmc21hbGxfaWNvbiwgMSk7CiAgICAgIGZyZWUod2luX2ljb25fZmls
ZSk7CiAgICB9CiNlbHNlCiAgICBjaGFyIHdpbl9pY29uX2ZpbGVbTUFYX1BB
VEhdOwogICAgY3lnd2luX2NvbnZfdG9fd2luMzJfcGF0aChpY29uX2ZpbGUs
IHdpbl9pY29uX2ZpbGUpOwogICAgRXh0cmFjdEljb25FeEEod2luX2ljb25f
ZmlsZSwgaWNvbl9pbmRleCwgJmxhcmdlX2ljb24sICZzbWFsbF9pY29uLCAx
KTsKI2VuZGlmCiAgICBpZiAoIWxhcmdlX2ljb24pIHsKICAgICAgc21hbGxf
aWNvbiA9IDA7CiAgICAgIHVpbnQgZXJyb3IgPSBHZXRMYXN0RXJyb3IoKTsK
ICAgICAgaWYgKGVycm9yKSB7CiAgICAgICAgY2hhciBtc2dbMTAyNF07CiAg
ICAgICAgRm9ybWF0TWVzc2FnZSgKICAgICAgICAgIEZPUk1BVF9NRVNTQUdF
X0ZST01fU1lTVEVNIHwgRk9STUFUX01FU1NBR0VfTUFYX1dJRFRIX01BU0ss
CiAgICAgICAgICAwLCBlcnJvciwgMCwgbXNnLCBzaXplb2YgbXNnLCAwCiAg
ICAgICAgKTsKICAgICAgICB3YXJuKCJjb3VsZCBub3QgbG9hZCBpY29uIGZy
b20gJyVzJzogJXMiLCBjZmcuaWNvbiwgbXNnKTsKICAgICAgfQogICAgICBl
bHNlCiAgICAgICAgd2FybigiY291bGQgbm90IGxvYWQgaWNvbiBmcm9tICcl
cyciLCBjZmcuaWNvbik7CiAgICB9CiAgICBkZWxldGUoaWNvbl9maWxlKTsK
ICB9CgogIC8vIFNldCB0aGUgQXBwSUQgaWYgc3BlY2lmaWVkIGFuZCB0aGUg
cmVxdWlyZWQgZnVuY3Rpb24gaXMgYXZhaWxhYmxlLgogIGlmICgqY2ZnLmFw
cF9pZCkgewogICAgSE1PRFVMRSBzaGVsbCA9IGxvYWRfc3lzX2xpYnJhcnko
InNoZWxsMzIuZGxsIik7CiAgICBIUkVTVUxUIChXSU5BUEkgKnBTZXRBcHBJ
RCkoUENXU1RSKSA9CiAgICAgICh2b2lkICopR2V0UHJvY0FkZHJlc3Moc2hl
bGwsICJTZXRDdXJyZW50UHJvY2Vzc0V4cGxpY2l0QXBwVXNlck1vZGVsSUQi
KTsKCiAgICBpZiAocFNldEFwcElEKSB7CiAgICAgIHNpemVfdCBzaXplID0g
Y3NfbWJzdG93Y3MoMCwgY2ZnLmFwcF9pZCwgMCkgKyAxOwogICAgICBpZiAo
c2l6ZSkgewogICAgICAgIHdjaGFyIGJ1ZltzaXplXTsKICAgICAgICBjc19t
YnN0b3djcyhidWYsIGNmZy5hcHBfaWQsIHNpemUpOwogICAgICAgIHBTZXRB
cHBJRChidWYpOwogICAgICB9CiAgICB9CiAgfQoKICBpbnN0ID0gR2V0TW9k
dWxlSGFuZGxlKE5VTEwpOwoKICAvLyBXaW5kb3cgY2xhc3MgbmFtZS4KICB3
c3RyaW5nIHdjbGFzcyA9IF9XKEFQUE5BTUUpOwogIGlmICgqY2ZnLmNsYXNz
KSB7CiAgICBzaXplX3Qgc2l6ZSA9IGNzX21ic3Rvd2NzKDAsIGNmZy5jbGFz
cywgMCkgKyAxOwogICAgaWYgKHNpemUpIHsKICAgICAgd2NoYXIgKmJ1ZiA9
IG5ld24od2NoYXIsIHNpemUpOwogICAgICBjc19tYnN0b3djcyhidWYsIGNm
Zy5jbGFzcywgc2l6ZSk7CiAgICAgIHdjbGFzcyA9IGJ1ZjsKICAgIH0KICAg
IGVsc2UKICAgICAgZnB1dHMoIlVzaW5nIGRlZmF1bHQgY2xhc3MgbmFtZSBk
dWUgdG8gaW52YWxpZCBjaGFyYWN0ZXJzLlxuIiwgc3RkZXJyKTsKICB9Cgog
IC8vIFB1dCBjaGlsZCBjb21tYW5kIGxpbmUgaW50byB3aW5kb3cgdGl0bGUg
aWYgd2UgaGF2ZW4ndCBnb3Qgb25lIGFscmVhZHkuCiAgc3RyaW5nIHRpdGxl
ID0gY2ZnLnRpdGxlOwogIGlmICghKnRpdGxlKSB7CiAgICBzaXplX3QgbGVu
OwogICAgY2hhciAqYXJnejsKICAgIGFyZ3pfY3JlYXRlKGFyZ3YsICZhcmd6
LCAmbGVuKTsKICAgIGFyZ3pfc3RyaW5naWZ5KGFyZ3osIGxlbiwgJyAnKTsK
ICAgIHRpdGxlID0gYXJnejsKICB9CgogIC8vIENvbnZlcnQgdGl0bGUgdG8g
VW5pY29kZS4gRGVmYXVsdCB0byBhcHBsaWNhdGlvbiBuYW1lIGlmIHVuc3Vj
Y2Vzc2Z1bC4KICB3c3RyaW5nIHd0aXRsZSA9IF9XKEFQUE5BTUUpOwogIHsK
ICAgIHNpemVfdCBzaXplID0gY3NfbWJzdG93Y3MoMCwgdGl0bGUsIDApICsg
MTsKICAgIGlmIChzaXplKSB7CiAgICAgIHdjaGFyICpidWYgPSBuZXduKHdj
aGFyLCBzaXplKTsKICAgICAgY3NfbWJzdG93Y3MoYnVmLCB0aXRsZSwgc2l6
ZSk7CiAgICAgIHd0aXRsZSA9IGJ1ZjsKICAgIH0KICAgIGVsc2UKICAgICAg
ZnB1dHMoIlVzaW5nIGRlZmF1bHQgdGl0bGUgZHVlIHRvIGludmFsaWQgY2hh
cmFjdGVycy5cbiIsIHN0ZGVycik7CiAgfQoKICAvLyBUaGUgd2luZG93IGNs
YXNzLgogIGNsYXNzX2F0b20gPSBSZWdpc3RlckNsYXNzRXhXKCYoV05EQ0xB
U1NFWFcpewogICAgLmNiU2l6ZSA9IHNpemVvZihXTkRDTEFTU0VYVyksCiAg
ICAuc3R5bGUgPSAwLAogICAgLmxwZm5XbmRQcm9jID0gd2luX3Byb2MsCiAg
ICAuY2JDbHNFeHRyYSA9IDAsCiAgICAuY2JXbmRFeHRyYSA9IDAsCiAgICAu
aEluc3RhbmNlID0gaW5zdCwKICAgIC5oSWNvbiA9IGxhcmdlX2ljb24gPzog
TG9hZEljb24oaW5zdCwgTUFLRUlOVFJFU09VUkNFKElESV9NQUlOSUNPTikp
LAogICAgLmhJY29uU20gPSBzbWFsbF9pY29uLAogICAgLmhDdXJzb3IgPSBM
b2FkQ3Vyc29yKG51bGwsIElEQ19JQkVBTSksCiAgICAuaGJyQmFja2dyb3Vu
ZCA9IG51bGwsCiAgICAubHBzek1lbnVOYW1lID0gbnVsbCwKICAgIC5scHN6
Q2xhc3NOYW1lID0gd2NsYXNzLAogIH0pOwoKCiAgLy8gSW5pdGlhbGlzZSB0
aGUgZm9udHMsIHRodXMgYWxzbyBkZXRlcm1pbmluZyB0aGVpciB3aWR0aCBh
bmQgaGVpZ2h0LgogIHdpbl9pbml0X2ZvbnRzKGNmZy5mb250LnNpemUpOwoK
ICAvLyBSZWNvbmZpZ3VyZSB0aGUgY2hhcnNldCBtb2R1bGUgbm93IHRoYXQg
YXJndW1lbnRzIGhhdmUgYmVlbiBjb252ZXJ0ZWQsCiAgLy8gdGhlIGxvY2Fs
ZS9jaGFyc2V0IHNldHRpbmdzIGhhdmUgYmVlbiBsb2FkZWQsIGFuZCB0aGUg
Zm9udCB3aWR0aCBoYXMKICAvLyBiZWVuIGRldGVybWluZWQuCiAgY3NfcmVj
b25maWcoKTsKCiAgLy8gRGV0ZXJtaW5lIHdpbmRvdyBzaXplcy4KICBpbnQg
dGVybV93aWR0aCA9IGZvbnRfd2lkdGggKiBjZmcuY29sczsKICBpbnQgdGVy
bV9oZWlnaHQgPSBmb250X2hlaWdodCAqIGNmZy5yb3dzOwoKICBSRUNUIGNy
ID0gezAsIDAsIHRlcm1fd2lkdGggKyAyICogUEFERElORywgdGVybV9oZWln
aHQgKyAyICogUEFERElOR307CiAgUkVDVCB3ciA9IGNyOwogIEFkanVzdFdp
bmRvd1JlY3QoJndyLCBXU19PVkVSTEFQUEVEV0lORE9XLCBmYWxzZSk7CiAg
aW50IHdpZHRoID0gd3IucmlnaHQgLSB3ci5sZWZ0OwogIGludCBoZWlnaHQg
PSB3ci5ib3R0b20gLSB3ci50b3A7CgogIGlmIChjZmcuc2Nyb2xsYmFyKQog
ICAgd2lkdGggKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoK
ICBleHRyYV93aWR0aCA9IHdpZHRoIC0gKGNyLnJpZ2h0IC0gY3IubGVmdCk7
CiAgZXh0cmFfaGVpZ2h0ID0gaGVpZ2h0IC0gKGNyLmJvdHRvbSAtIGNyLnRv
cCk7CgogIC8vIEhhdmluZyB4ID09IENXX1VTRURFRkFVTFQgYnV0IG5vdCBz
dGlsbCB0cmlnZ2VycyB0aGUgZGVmYXVsdCBwb3NpdGlvbmluZywKICAvLyB3
aGVyZWFzIHk9PUNXX1VTRUZBVUxUIGJ1dCBub3QgeCByZXN1bHRzIGluIGFu
IGludmlzaWJsZSB3aW5kb3csIHNvIHRvCiAgLy8gYXZvaWQgdGhlIGxhdHRl
ciwgcmVxdWlyZSBib3RoIHggYW5kIHkgdG8gYmUgc2V0IGZvciBjdXN0b20g
cG9zaXRpb25pbmcuCiAgaWYgKGNmZy55ID09IChpbnQpQ1dfVVNFREVGQVVM
VCkKICAgIGNmZy54ID0gQ1dfVVNFREVGQVVMVDsKCiAgLy8gQ3JlYXRlIGlu
aXRpYWwgd2luZG93LgogIHduZCA9IENyZWF0ZVdpbmRvd0V4VyhjZmcuc2Ny
b2xsYmFyIDwgMCA/IFdTX0VYX0xFRlRTQ1JPTExCQVIgOiAwLAogICAgICAg
ICAgICAgICAgICAgICAgICB3Y2xhc3MsIHd0aXRsZSwKICAgICAgICAgICAg
ICAgICAgICAgICAgV1NfT1ZFUkxBUFBFRFdJTkRPVyB8IChjZmcuc2Nyb2xs
YmFyID8gV1NfVlNDUk9MTCA6IDApLAogICAgICAgICAgICAgICAgICAgICAg
ICBjZmcueCwgY2ZnLnksIHdpZHRoLCBoZWlnaHQsCiAgICAgICAgICAgICAg
ICAgICAgICAgIG51bGwsIG51bGwsIGluc3QsIG51bGwpOwoKICBpZiAoYm9y
ZGVyX3N0eWxlKSB7CiAgICBMT05HIHN0eWxlID0gR2V0V2luZG93TG9uZyh3
bmQsIEdXTF9TVFlMRSk7CiAgICBpZiAoc3RyY21wIChib3JkZXJfc3R5bGUs
ICJ2b2lkIikgPT0gMCkgewogICAgICBzdHlsZSAmPSB+KFdTX0NBUFRJT04g
fCBXU19CT1JERVIgfCBXU19USElDS0ZSQU1FKTsKICAgIH0KICAgIGVsc2Ug
ewogICAgICBzdHlsZSAmPSB+KFdTX0NBUFRJT04gfCBXU19CT1JERVIpOwog
ICAgfQogICAgU2V0V2luZG93TG9uZyh3bmQsIEdXTF9TVFlMRSwgc3R5bGUp
OwogICAgU2V0V2luZG93UG9zKHduZCwgbnVsbCwgMCwgMCwgMCwgMCwKICAg
ICAgICAgICAgICAgICBTV1BfTk9NT1ZFIHwgU1dQX05PU0laRSB8IFNXUF9O
T1pPUkRFUiB8IFNXUF9GUkFNRUNIQU5HRUQpOwogIH0KCiAgLy8gVGhlIGlu
cHV0IG1ldGhvZCBjb250ZXh0LgogIGltYyA9IEltbUdldENvbnRleHQod25k
KTsKCiAgLy8gQ29ycmVjdCBhdXRvcGxhY2VtZW50LCB3aGljaCBsaWtlcyB0
byBwdXQgcGFydCBvZiB0aGUgd2luZG93IHVuZGVyIHRoZQogIC8vIHRhc2ti
YXIgd2hlbiB0aGUgd2luZG93IHNpemUgYXBwcm9hY2hlcyB0aGUgd29yayBh
cmVhIHNpemUuCiAgaWYgKGNmZy54ID09IChpbnQpQ1dfVVNFREVGQVVMVCkg
ewogICAgd2luX2ZpeF9wb3NpdGlvbigpOwogIH0KCiAgLy8gSW5pdGlhbGlz
ZSB0aGUgdGVybWluYWwuCiAgdGVybV9yZXNldCgpOwogIHRlcm1fcmVzaXpl
KGNmZy5yb3dzLCBjZmcuY29scyk7CgogIC8vIEluaXRpYWxpc2UgdGhlIHNj
cm9sbCBiYXIuCiAgU2V0U2Nyb2xsSW5mbygKICAgIHduZCwgU0JfVkVSVCwK
ICAgICYoU0NST0xMSU5GTyl7CiAgICAgIC5jYlNpemUgPSBzaXplb2YoU0NS
T0xMSU5GTyksCiAgICAgIC5mTWFzayA9IFNJRl9BTEwgfCBTSUZfRElTQUJM
RU5PU0NST0xMLAogICAgICAubk1pbiA9IDAsIC5uTWF4ID0gY2ZnLnJvd3Mg
LSAxLAogICAgICAublBhZ2UgPSBjZmcucm93cywgLm5Qb3MgPSAwLAogICAg
fSwKICAgIGZhbHNlCiAgKTsKCiAgLy8gU2V0IHVwIGFuIGVtcHR5IGNhcmV0
IGJpdG1hcC4gV2UncmUgcGFpbnRpbmcgdGhlIGN1cnNvciBtYW51YWxseS4K
ICBjYXJldGJtID0gQ3JlYXRlQml0bWFwKDEsIGZvbnRfaGVpZ2h0LCAxLCAx
LCBuZXduKHNob3J0LCBmb250X2hlaWdodCkpOwogIENyZWF0ZUNhcmV0KHdu
ZCwgY2FyZXRibSwgMCwgMCk7CgogIC8vIEluaXRpYWxpc2UgdmFyaW91cyBv
dGhlciBzdHVmZi4KICB3aW5faW5pdF9kcm9wX3RhcmdldCgpOwogIHdpbl9p
bml0X21lbnVzKCk7CiAgdXBkYXRlX3RyYW5zcGFyZW5jeSgpOwoKICAvLyBD
cmVhdGUgY2hpbGQgcHJvY2Vzcy4KICBjaGlsZF9jcmVhdGUoCiAgICBhcmd2
LCAmKHN0cnVjdCB3aW5zaXplKXtjZmcucm93cywgY2ZnLmNvbHMsIHRlcm1f
d2lkdGgsIHRlcm1faGVpZ2h0fQogICk7CgogIC8vIEZpbmFsbHkgc2hvdyB0
aGUgd2luZG93IQogIGZ1bGxzY3Jfb25fbWF4ID0gKGNmZy53aW5kb3cgPT0g
LTEpOwogIFNob3dXaW5kb3cod25kLCBmdWxsc2NyX29uX21heCA/IFNXX1NI
T1dNQVhJTUlaRUQgOiBjZmcud2luZG93KTsKCiAgLy8gTWVzc2FnZSBsb29w
LgogIGZvciAoOzspIHsKICAgIE1TRyBtc2c7CiAgICB3aGlsZSAoUGVla01l
c3NhZ2UoJm1zZywgbnVsbCwgMCwgMCwgUE1fUkVNT1ZFKSkgewogICAgICBp
ZiAobXNnLm1lc3NhZ2UgPT0gV01fUVVJVCkKICAgICAgICByZXR1cm4gbXNn
LndQYXJhbTsKICAgICAgaWYgKCFJc0RpYWxvZ01lc3NhZ2UoY29uZmlnX3du
ZCwgJm1zZykpCiAgICAgICAgRGlzcGF0Y2hNZXNzYWdlKCZtc2cpOwogICAg
fQogICAgY2hpbGRfcHJvYygpOwogIH0KfQo=


------=_20150727175807_31619
Content-Type: text/plain; charset=us-ascii

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
------=_20150727175807_31619--


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019