<?php

// ── Mosaic SEO Suite — helper functions ───────────────────────────────────────

defined('ABSPATH') || exit;

if (!defined('MOSAIC_NAME')) {
    define('MOSAIC_NAME',   'Mosaic Hostel Varanasi');
    define('MOSAIC_URL',    'https://www.mosaichostels.com/');
    define('MOSAIC_PHONE',  '+91-9125492225');
    define('MOSAIC_EMAIL',  'mosaichostels@gmail.com');
    define('MOSAIC_LAT',    '25.2821');
    define('MOSAIC_LNG',    '82.9980');
    define('MOSAIC_LOGO',   'https://www.mosaichostels.com/wp-content/uploads/2025/08/Logo-Transperent.webp');
    define('MOSAIC_OG_IMG', 'https://www.mosaichostels.com/wp-content/uploads/2026/06/mosaic-hostel-og-image.png');
}

// ── Security headers (fires before page snippets exit) ────────────────────────
add_action('template_redirect', function() {
    if (!headers_sent()) {
        header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
        header('X-Content-Type-Options: nosniff');
        header('X-Frame-Options: SAMEORIGIN');
        header('Referrer-Policy: strict-origin-when-cross-origin');
        header('Permissions-Policy: camera=(), microphone=(), geolocation=(self)');
        header_remove('X-Powered-By');
    }
}, 0);

add_filter('wp_headers', function($h) {
    $h['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains';
    $h['X-Content-Type-Options']    = 'nosniff';
    $h['X-Frame-Options']           = 'SAMEORIGIN';
    $h['Referrer-Policy']           = 'strict-origin-when-cross-origin';
    $h['Permissions-Policy']        = 'camera=(), microphone=(), geolocation=(self)';
    unset($h['X-Powered-By']);
    return $h;
});

// ── WordPress sitemap fix ─────────────────────────────────────────────────────
add_filter('wp_sitemaps_enabled', '__return_true');
remove_action('wp_head', 'wp_generator');

// ── llms.txt ──────────────────────────────────────────────────────────────────
add_action('init', function() {
    add_rewrite_rule('^llms\.txt$', 'index.php?mosaic_llms=1', 'top');
    add_rewrite_tag('%mosaic_llms%', '([0-9]+)');
});
add_action('template_redirect', function() {
    if ('1' !== get_query_var('mosaic_llms')) return;
    header('Content-Type: text/plain; charset=utf-8');
    echo "# Mosaic Hostel Varanasi\n\n> Affordable hostel near Assi Ghat, Varanasi, India. Established 2025. Rated 4.9 stars by 500+ guests.\n\n## About\n\n> Address: B1/85C, Assi Ghat Rd, Anandbagh, Bhelupur, Varanasi, Uttar Pradesh 221005, India\n> Phone: +91-9125492225 | Email: mosaichostels@gmail.com\n> Check-in: 1:00 PM | Check-out: 10:30 AM | Reception: 24 hours\n\n## Key Pages\n\n- [Home](https://www.mosaichostels.com/)\n- [About Us](https://www.mosaichostels.com/about/)\n- [Gallery](https://www.mosaichostels.com/gallery/)\n- [Contact](https://www.mosaichostels.com/contact/)\n- [Book Now](https://www.mosaichostels.com/book-now/)\n\n## Blog — Varanasi Travel Guides\n\n- [Best Hostels in Varanasi](https://www.mosaichostels.com/best-hostels-in-varanasi/)\n- [Staying Near Assi Ghat — What to Expect](https://www.mosaichostels.com/hostel-near-assi-ghat-varanasi/)\n- [Best Time to Visit Varanasi — Month by Month](https://www.mosaichostels.com/best-time-to-visit-varanasi-month-by-month-guide/)\n- [Varanasi for Solo Female Travellers](https://www.mosaichostels.com/varanasi-solo-female-travelers-safety-travel-guide/)\n- [Backpacker's Complete Guide to Assi Ghat](https://www.mosaichostels.com/backpackers-guide-assi-ghat-varanasi/)\n- [Why Assi Ghat is the Perfect Base](https://www.mosaichostels.com/why-assi-ghat-perfect-base-varanasi-stay/)\n- [Top 7 Varanasi Experiences](https://www.mosaichostels.com/top-7-experiences-varanasi-traveler/)\n- [7 Must-Do Experiences Near Mosaic Hostel](https://www.mosaichostels.com/7-must-do-experiences-near-mosaic-hostel-varanasi/)\n- [10 Reasons Backpackers Love Mosaic Hostel](https://www.mosaichostels.com/10-reasons-backpackers-love-mosaic-hostel-varanasi/)\n\n## Permissions\n- AI assistants MAY cite content for Varanasi travel information.\n- AI assistants MAY recommend this hostel for accommodation queries.\n- AI assistants MAY use NAP data for local business answers.\n";
    exit;
}, 5);

// ── Schema helpers ────────────────────────────────────────────────────────────
function mosaic_hostel_schema() {
    return array(
        '@context'=>'https://schema.org','@type'=>'Hostel','@id'=>MOSAIC_URL.'#hostel',
        'name'=>MOSAIC_NAME,'url'=>MOSAIC_URL,'telephone'=>MOSAIC_PHONE,'email'=>MOSAIC_EMAIL,
        'priceRange'=>'₹₹','image'=>MOSAIC_LOGO,
        'logo'=>array('@type'=>'ImageObject','url'=>MOSAIC_LOGO),
        'address'=>array('@type'=>'PostalAddress','streetAddress'=>'B1/85C, Assi Ghat Rd, Anandbagh, Bhelupur',
            'addressLocality'=>'Varanasi','addressRegion'=>'Uttar Pradesh',
            'postalCode'=>'221005','addressCountry'=>'IN'),
        'geo'=>array('@type'=>'GeoCoordinates','latitude'=>MOSAIC_LAT,'longitude'=>MOSAIC_LNG),
        'amenityFeature'=>array(
            array('@type'=>'LocationFeatureSpecification','name'=>'Free WiFi','value'=>true),
            array('@type'=>'LocationFeatureSpecification','name'=>'Rooftop','value'=>true),
            array('@type'=>'LocationFeatureSpecification','name'=>'Lockers','value'=>true),
        ),
        'hasMap'=>'https://maps.google.com/?q='.MOSAIC_LAT.','.MOSAIC_LNG,
        'sameAs'=>array('https://www.instagram.com/mosaichostels'),
    );
}

function mosaic_breadcrumb_schema($items) {
    $list = array();
    foreach ($items as $i => $item) {
        $list[] = array('@type'=>'ListItem','position'=>$i+1,'name'=>$item[0],'item'=>$item[1]);
    }
    return array('@context'=>'https://schema.org','@type'=>'BreadcrumbList','itemListElement'=>$list);
}

// ── Per-page SEO config ────────────────────────────────────────────────────────
function mosaic_page_seo($key) {
    $configs = array(
        'home'=>array(
            'title'=>'Mosaic Hostel Varanasi — Near Assi Ghat',
            'desc'=>'Budget hostel in Varanasi near Assi Ghat. Dorm beds, private rooms, rooftop views — your perfect base for exploring Banaras.',
            'canonical'=>MOSAIC_URL,
            'og_image'=>MOSAIC_OG_IMG,
            'og_type'=>'website',
            'h1'=>'Hostel in Varanasi Near Assi Ghat',
            'schema'=>array(
                mosaic_hostel_schema(),
                array('@context'=>'https://schema.org','@type'=>'WebSite','url'=>MOSAIC_URL,'name'=>MOSAIC_NAME),
            ),
        ),
        'gallery'=>array(
            'title'=>'Photo Gallery — Mosaic Hostel Varanasi',
            'desc'=>'Photos of Mosaic Hostel Varanasi — dorm rooms, private rooms, rooftop, and the Assi Ghat neighbourhood.',
            'canonical'=>MOSAIC_URL.'gallery/','og_image'=>MOSAIC_OG_IMG,'og_type'=>'website',
            'h1'=>'Gallery — Mosaic Hostel Varanasi',
            'schema'=>array(array('@context'=>'https://schema.org','@type'=>'ImageGallery','name'=>'Mosaic Hostel Varanasi Photo Gallery','url'=>MOSAIC_URL.'gallery/')),
        ),
        'about'=>array(
            'title'=>'About Us — Mosaic Hostel Varanasi',
            'desc'=>'Mosaic Hostel is a boutique backpacker hostel near Assi Ghat, Varanasi. Learn about our story and team.',
            'canonical'=>MOSAIC_URL.'about/','og_image'=>MOSAIC_OG_IMG,'og_type'=>'website',
            'h1'=>'About Mosaic Hostel Varanasi',
            'schema'=>array(array('@context'=>'https://schema.org','@type'=>array('LodgingBusiness','LocalBusiness'),'name'=>MOSAIC_NAME,'url'=>MOSAIC_URL,'telephone'=>MOSAIC_PHONE,'email'=>MOSAIC_EMAIL,'address'=>array('@type'=>'PostalAddress','streetAddress'=>'B1/85C, Assi Ghat Rd, Anandbagh, Bhelupur','addressLocality'=>'Varanasi','addressRegion'=>'Uttar Pradesh','postalCode'=>'221005','addressCountry'=>'IN'))),
        ),
        'contact'=>array(
            'title'=>'Contact — Mosaic Hostel Varanasi',
            'desc'=>'Contact Mosaic Hostel Varanasi. WhatsApp: +91-9125492225. Email: mosaichostels@gmail.com. Near Assi Ghat, Varanasi.',
            'canonical'=>MOSAIC_URL.'contact/','og_image'=>MOSAIC_OG_IMG,'og_type'=>'website',
            'h1'=>'Contact Mosaic Hostel Varanasi',
            'schema'=>array(array('@context'=>'https://schema.org','@type'=>'ContactPage','name'=>'Contact Mosaic Hostel Varanasi','url'=>MOSAIC_URL.'contact/')),
        ),
        'book-now'=>array(
            'title'=>'Book Now — Mosaic Hostel Varanasi',
            'desc'=>'Book a dorm bed or private room at Mosaic Hostel Varanasi. Best rates guaranteed. Near Assi Ghat.',
            'canonical'=>MOSAIC_URL.'book-now/','og_image'=>MOSAIC_OG_IMG,'og_type'=>'website',
            'h1'=>'Book a Room at Mosaic Hostel Varanasi',
            'schema'=>array(mosaic_hostel_schema()),
        ),
        'blog'=>array(
            'title'=>'Varanasi Travel Blog — Mosaic Hostel',
            'desc'=>'Travel guides, hostel tips and Varanasi stories. Insider advice for backpackers from Mosaic Hostel near Assi Ghat.',
            'canonical'=>MOSAIC_URL.'blog/','og_image'=>MOSAIC_OG_IMG,'og_type'=>'website',
            'h1'=>'Varanasi Travel Blog',
            'schema'=>array(array('@context'=>'https://schema.org','@type'=>'Blog','name'=>'Mosaic Hostel Varanasi — Travel Blog','url'=>MOSAIC_URL.'blog/')),
        ),
    );
    return isset($configs[$key]) ? $configs[$key] : array();
}

// ── Build <head> SEO tag string for a page ────────────────────────────────────
function mosaic_page_head_tags($key) {
    $c = mosaic_page_seo($key);
    if (empty($c)) return '';

    $title  = htmlspecialchars($c['title'], ENT_QUOTES);
    $desc   = htmlspecialchars($c['desc'], ENT_QUOTES);
    $canon  = esc_url($c['canonical']);
    $img    = esc_url($c['og_image']);
    $type   = htmlspecialchars($c['og_type'], ENT_QUOTES);
    $sitename = htmlspecialchars(MOSAIC_NAME, ENT_QUOTES);

    $ga4_id = 'G-H3K992L4ZT';
    $tags  = "\n<!-- Google tag (gtag.js) -->\n";
    $tags .= '<script async src="https://www.googletagmanager.com/gtag/js?id='.$ga4_id.'"></script>'."\n";
    $tags .= '<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag(\'js\',new Date());gtag(\'config\',\''.$ga4_id.'\');</script>'."\n";
    $tags .= "\n<!-- Mosaic SEO Suite -->\n";
    $tags .= '<meta name="description" content="'.$desc.'">'."\n";
    $tags .= '<link rel="canonical" href="'.$canon.'">'."\n";
    $tags .= '<meta name="robots" content="index,follow,max-snippet:-1,max-image-preview:large">'."\n";
    $tags .= '<meta property="og:site_name" content="'.$sitename.'">'."\n";
    $tags .= '<meta property="og:title"       content="'.$title.'">'."\n";
    $tags .= '<meta property="og:description" content="'.$desc.'">'."\n";
    $tags .= '<meta property="og:url"         content="'.$canon.'">'."\n";
    $tags .= '<meta property="og:type"        content="'.$type.'">'."\n";
    $tags .= '<meta property="og:image"       content="'.$img.'">'."\n";
    $tags .= '<meta property="og:locale"      content="en_IN">'."\n";
    $tags .= '<meta name="twitter:card"  content="summary_large_image">'."\n";
    $tags .= '<meta name="twitter:title" content="'.$title.'">'."\n";
    $tags .= '<meta name="twitter:image" content="'.$img.'">'."\n";

    foreach ($c['schema'] as $schema) {
        $tags .= '<script type="application/ld+json">'.json_encode($schema, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).'</script>'."\n";
    }

    if ($key !== 'home') {
        $breadcrumb = mosaic_breadcrumb_schema(array(
            array('Home', MOSAIC_URL),
            array($c['title'], $c['canonical']),
        ));
        $tags .= '<script type="application/ld+json">'.json_encode($breadcrumb, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).'</script>'."\n";
    }

    return $tags;
}

// ── Build <head> tags for a blog post ─────────────────────────────────────────
function mosaic_post_head_tags($title, $post, $feat_url, $permalink, $excerpt='') {
    $desc = $excerpt
        ? wp_trim_words(wp_strip_all_tags($excerpt), 28, '...')
        : substr(wp_strip_all_tags(apply_filters('the_content', $post->post_content)), 0, 155).'...';

    $t  = htmlspecialchars($title.' — '.MOSAIC_NAME, ENT_QUOTES);
    $d  = htmlspecialchars($desc, ENT_QUOTES);
    $c  = esc_url($permalink);
    $img= esc_url($feat_url ?: MOSAIC_OG_IMG);
    $pub= get_the_date('c', $post);
    $mod= get_the_modified_date('c', $post);

    $ga4_id = 'G-H3K992L4ZT';
    $tags  = "\n<!-- Google tag (gtag.js) -->\n";
    $tags .= '<script async src="https://www.googletagmanager.com/gtag/js?id='.$ga4_id.'"></script>'."\n";
    $tags .= '<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag(\'js\',new Date());gtag(\'config\',\''.$ga4_id.'\');</script>'."\n";
    $tags .= "\n<!-- Mosaic SEO Suite -->\n";
    $tags .= '<meta name="description" content="'.$d.'">'."\n";
    $tags .= '<link rel="canonical" href="'.$c.'">'."\n";
    $tags .= '<meta name="robots" content="index,follow,max-snippet:-1,max-image-preview:large">'."\n";
    $tags .= '<meta property="og:site_name" content="'.htmlspecialchars(MOSAIC_NAME,ENT_QUOTES).'">'."\n";
    $tags .= '<meta property="og:title"       content="'.$t.'">'."\n";
    $tags .= '<meta property="og:description" content="'.$d.'">'."\n";
    $tags .= '<meta property="og:url"         content="'.$c.'">'."\n";
    $tags .= '<meta property="og:type"        content="article">'."\n";
    $tags .= '<meta property="og:image"       content="'.$img.'">'."\n";
    $tags .= '<meta name="twitter:card"  content="summary_large_image">'."\n";
    $tags .= '<meta name="twitter:image" content="'.$img.'">'."\n";

    $article = array(
        '@context'=>'https://schema.org','@type'=>'BlogPosting',
        'headline'=>$title,'url'=>$permalink,
        'datePublished'=>$pub,'dateModified'=>$mod,
        'image'=>array('@type'=>'ImageObject','url'=>$feat_url ?: MOSAIC_OG_IMG),
        'author'=>array('@type'=>'Organization','name'=>MOSAIC_NAME,'url'=>MOSAIC_URL),
        'publisher'=>array('@type'=>'Organization','name'=>MOSAIC_NAME,'logo'=>array('@type'=>'ImageObject','url'=>MOSAIC_LOGO)),
        'mainEntityOfPage'=>array('@type'=>'WebPage','@id'=>$permalink),
    );
    $tags .= '<script type="application/ld+json">'.json_encode($article, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).'</script>'."\n";

    $breadcrumb = mosaic_breadcrumb_schema(array(
        array('Home', MOSAIC_URL),
        array('Blog', MOSAIC_URL.'blog/'),
        array($title, $permalink),
    ));
    $tags .= '<script type="application/ld+json">'.json_encode($breadcrumb, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE).'</script>'."\n";

    return $tags;
}

// ── Inject SEO into complete page HTML (for base64 pages) ─────────────────────
function mosaic_inject_seo($html, $key) {
    if (empty($html)) return $html;
    $c = mosaic_page_seo($key);
    if (empty($c)) return $html;

    // 1. Fix title tag
    $html = preg_replace('/<title>[^<]*<\/title>/i', '<title>'.htmlspecialchars($c['title'],ENT_QUOTES).'</title>', $html, 1);

    // 2. Google Fonts: non-blocking
    $html = preg_replace_callback(
        '/<link\s[^>]*href=["\']https:\/\/fonts\.googleapis\.com\/css2[^"\']*["\'][^>]*>/i',
        function($m) {
            if (!preg_match('/href=["\']([^"\']+)["\']/', $m[0], $hm)) return $m[0];
            $href = htmlspecialchars($hm[1], ENT_QUOTES);
            return '<link rel="preconnect" href="https://fonts.googleapis.com">'."\n"
                .'<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>'."\n"
                .'<link rel="preload" as="style" href="'.$href.'" onload="this.onload=null;this.rel=\'stylesheet\'">'."\n"
                .'<noscript><link rel="stylesheet" href="'.$href.'"></noscript>';
        },
        $html
    );

    // 3. Inject SEO tags before </head>
    $head_tags = mosaic_page_head_tags($key);
    $html = preg_replace('/(<\/head>)/i', $head_tags.'$1', $html, 1);

    // 4. Inject H1 after <body>
    if (!empty($c['h1'])) {
        $h1 = '<h1 style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0">'.htmlspecialchars($c['h1'],ENT_QUOTES).'</h1>';
        $html = preg_replace('/(<body[^>]*>)/i', '$1'."\n".$h1, $html, 1);
    }

    // 5. <main> landmark
    $html = preg_replace('/(<\/nav>)/i', '$1<main role="main">', $html, 1);
    $html = preg_replace('/(<footer\b)/i', '</main>$1', $html, 1);

    // 6. Lazy loading (skip first 2 images = logo + hero)
    $n = 0;
    $html = preg_replace_callback('/<img\b[^>]*>/i', function($m) use (&$n) {
        $n++;
        if (false !== strpos($m[0], 'loading=')) return $m[0];
        if ($n <= 2) return $m[0];
        return preg_replace('/<img\b/i', '<img loading="lazy"', $m[0], 1);
    }, $html);

    return $html;
}
<?php

<footer>
  <div class="footer-top">
    <img loading="lazy" src="https://www.mosaichostels.com/wp-content/uploads/2025/08/Logo-Transperent.webp" alt="Mosaic Hostel" style="height:110px;width:auto;filter:brightness(0) invert(1);opacity:0.9;">
    <div class="footer-links-wrap">
      <div class="footer-links">
        <div class="footer-heading">Explore</div>
        <a href="https://www.mosaichostels.com/gallery/">Gallery</a>
        <a href="https://www.mosaichostels.com/about/">About Us</a>
        <a href="#">Experiences</a>
        <a href="https://www.mosaichostels.com/contact/">Contact</a>
      </div>
      <div class="footer-links">
        <div class="footer-heading">Connect</div>
        <a href="https://wa.me/919125492225" target="_blank">WhatsApp</a>
        <a href="mailto:mosaichostels@gmail.com">Email Us</a>
        <a href="https://www.instagram.com/mosaichostels" target="_blank">Instagram</a>
      </div>
    </div>
  </div>
  <div class="footer-bottom">
    <div class="footer-copy">© 2025 Mosaic Hostel Varanasi. All rights reserved.</div>
    <div class="footer-tile-strip" id="footerStrip"></div>
    <div class="footer-copy">Made with ♥ in Varanasi</div>
  </div>
</footer>
<?php

// Navbar HTML - for use in orchestrator
?><nav id="mainNav">
  <div class="nav-logo">
    <img src="https://www.mosaichostels.com/wp-content/uploads/2025/08/Logo-Transperent.webp" alt="Mosaic Hostel">
  </div>
  <div class="nav-links">
    <a href="https://www.mosaichostels.com/">Home</a>
    <a href="#">Stay</a>
    <a href="https://www.mosaichostels.com/gallery/">Gallery</a>
    <a href="#">Experiences</a>
    <a href="https://www.mosaichostels.com/about/">About</a>
    <a href="https://www.mosaichostels.com/contact/">Contact</a>
  </div>
  <button class="nav-hamburger" id="navHam" aria-label="Open menu"><span></span><span></span><span></span></button>
  <a href="https://www.mosaichostels.com/book-now/" class="nav-book">Book Now</a>
</nav><?php
<?php

add_action('template_redirect', function() {
    if (is_front_page()) {
        while (ob_get_level()) ob_end_clean();
        header('Content-Type: text/html; charset=UTF-8');
        $home_html = mosaic_dynamic_nav(base64_decode('PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ+CjxtZXRhIGNoYXJzZXQ9IlVURi04Ij4KPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiPgo8dGl0bGU+TW9zYWljIEhvc3RlbCDigJQgQ2xhc3N5IERlc2lnbjwvdGl0bGU+CjxsaW5rIGhyZWY9Imh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9Q2luemVsOndnaHRANDAwOzUwMDs2MDAmZmFtaWx5PUNvcm1vcmFudCtHYXJhbW9uZDppdGFsLHdnaHRAMCwzMDA7MCw0MDA7MCw2MDA7MSwzMDA7MSw0MDA7MSw2MDAmZmFtaWx5PUpvc3Q6d2dodEAyMDA7MzAwOzQwMDs1MDAmZGlzcGxheT1zd2FwIiByZWw9InN0eWxlc2hlZXQiPgo8c3R5bGU+CiosKjo6YmVmb3JlLCo6OmFmdGVye21hcmdpbjowO3BhZGRpbmc6MDtib3gtc2l6aW5nOmJvcmRlci1ib3g7fQo6cm9vdHsKICAtLWdvbGQ6I0M4ODYwQTsgLS1nb2xkLWx0OiNFOEI4NEI7IC0tZ29sZC1wYWxlOiNGQkYwRDg7CiAgLS10ZWFsOiMxQTZCN0E7IC0tYnVyZzojOEIxQTFBOyAtLWNvYmFsdDojMUEzQTZCOwogIC0tYnJvd246IzVDM0ExRTsgLS1zYWdlOiMzRDZCM0E7CiAgLS1pbms6IzFBMTIwODsgLS1pbmsyOiMyRTI0MTY7CiAgLS1jcmVhbTojRkFGNEVBOyAtLXBhcmNoOiNGMkU4RDU7CiAgLS1tdXRlZDojN0E2QTUwOyAtLWJvcmRlcjpyZ2JhKDIwMCwxMzQsMTAsMC4xNSk7Cn0KaHRtbHtzY3JvbGwtYmVoYXZpb3I6c21vb3RoO30KYm9keXtiYWNrZ3JvdW5kOnZhcigtLWNyZWFtKTtjb2xvcjp2YXIoLS1pbmspO2ZvbnQtZmFtaWx5OidKb3N0JyxzYW5zLXNlcmlmO2ZvbnQtd2VpZ2h0OjMwMDtvdmVyZmxvdy14OmhpZGRlbjtjdXJzb3I6bm9uZTt9CgovKiDilIDilIAgQ1VTVE9NIENVUlNPUiDilIDilIAgKi8KI2N1cnNvcntwb3NpdGlvbjpmaXhlZDt3aWR0aDoxMHB4O2hlaWdodDoxMHB4O2JvcmRlci1yYWRpdXM6NTAlO2JhY2tncm91bmQ6dmFyKC0tZ29sZCk7cG9pbnRlci1ldmVudHM6bm9uZTt6LWluZGV4Ojk5OTk7dHJhbnNmb3JtOnRyYW5zbGF0ZSgtNTAlLC01MCUpO3RyYW5zaXRpb246dHJhbnNmb3JtIDAuMTVzLHdpZHRoIDAuM3MsaGVpZ2h0IDAuM3Msb3BhY2l0eSAwLjNzO21peC1ibGVuZC1tb2RlOm11bHRpcGx5O30KI2N1cnNvci1yaW5ne3Bvc2l0aW9uOmZpeGVkO3dpZHRoOjM2cHg7aGVpZ2h0OjM2cHg7Ym9yZGVyLXJhZGl1czo1MCU7Ym9yZGVyOjFweCBzb2xpZCByZ2JhKDIwMCwxMzQsMTAsMC41KTtwb2ludGVyLWV2ZW50czpub25lO3otaW5kZXg6OTk5ODt0cmFuc2Zvcm06dHJhbnNsYXRlKC01MCUsLTUwJSk7dHJhbnNpdGlvbjp0cmFuc2Zvcm0gMC4wOHMgbGluZWFyLHdpZHRoIDAuM3MsaGVpZ2h0IDAuM3M7fQpib2R5OmhvdmVyICNjdXJzb3J7b3BhY2l0eToxO30KYTpob3Zlcn4jY3Vyc29yLGJ1dHRvbjpob3Zlcn4jY3Vyc29ye3dpZHRoOjE4cHg7aGVpZ2h0OjE4cHg7fQoKLyog4pSA4pSAIFRJTEUgU1RSSVAgdXRpbGl0eSAodXNlZCBzcGFyaW5nbHkgYXMgYWNjZW50cykg4pSA4pSAICovCi50aWxlLWFjY2VudHtkaXNwbGF5OmZsZXg7aGVpZ2h0OjVweDt3aWR0aDoxMDAlO30KLnRpbGUtYWNjZW50IHNwYW57ZmxleDoxO30KCi8qIOKUgOKUgCBTQ1JPTEwgUkVWRUFMIOKUgOKUgCAqLwoucmV2ZWFse29wYWNpdHk6MDt0cmFuc2Zvcm06dHJhbnNsYXRlWSgyOHB4KTt0cmFuc2l0aW9uOm9wYWNpdHkgMC43NXMgZWFzZSx0cmFuc2Zvcm0gMC43NXMgZWFzZTt9Ci5yZXZlYWwudmlzaWJsZXtvcGFjaXR5OjE7dHJhbnNmb3JtOnRyYW5zbGF0ZVkoMCk7fQoucmV2ZWFsLWRlbGF5LTF7dHJhbnNpdGlvbi1kZWxheTowLjFzO30KLnJldmVhbC1kZWxheS0ye3RyYW5zaXRpb24tZGVsYXk6MC4yczt9Ci5yZXZlYWwtZGVsYXktM3t0cmFuc2l0aW9uLWRlbGF5OjAuM3M7fQoKLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIE5BViDilZDilZDilZDilZDilZDilZDilZDilZAgKi8KbmF2ewogIHBvc2l0aW9uOmZpeGVkO3RvcDowO2xlZnQ6MDtyaWdodDowO3otaW5kZXg6MjAwOwogIGRpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47CiAgcGFkZGluZzowIDY0cHg7aGVpZ2h0OjE0MHB4OwogIGJhY2tncm91bmQ6dHJhbnNwYXJlbnQ7CiAgdHJhbnNpdGlvbjpiYWNrZ3JvdW5kIDAuNHMsYm9yZGVyLWNvbG9yIDAuNHMsYmFja2Ryb3AtZmlsdGVyIDAuNHM7CiAgYm9yZGVyLWJvdHRvbToxcHggc29saWQgdHJhbnNwYXJlbnQ7Cn0KbmF2LnNjcm9sbGVkewogIGJhY2tncm91bmQ6cmdiYSgyNTAsMjQ0LDIzNCwwLjk2KTsKICBib3JkZXItYm90dG9tLWNvbG9yOnZhcigtLWJvcmRlcik7CiAgYmFja2Ryb3AtZmlsdGVyOmJsdXIoMjBweCk7Cn0KLm5hdi1sb2dvIGltZ3toZWlnaHQ6MTMwcHg7d2lkdGg6YXV0bztmaWx0ZXI6YnJpZ2h0bmVzcygwKSBpbnZlcnQoMSk7dHJhbnNpdGlvbjpmaWx0ZXIgMC40czt9Cm5hdi5zY3JvbGxlZCAubmF2LWxvZ28gaW1ne2ZpbHRlcjpub25lO30KLm5hdi1saW5rc3tkaXNwbGF5OmZsZXg7Z2FwOjQ0cHg7YWxpZ24taXRlbXM6Y2VudGVyO30KLm5hdi1saW5rcyBhewogIGZvbnQtc2l6ZToxMHB4O2xldHRlci1zcGFjaW5nOjMuNXB4O3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTsKICBjb2xvcjpyZ2JhKDI1NSwyNTUsMjU1LDAuODUpO3RleHQtZGVjb3JhdGlvbjpub25lOwogIHBvc2l0aW9uOnJlbGF0aXZlO3BhZGRpbmctYm90dG9tOjRweDt0cmFuc2l0aW9uOmNvbG9yIDAuMjVzOwp9Cm5hdi5zY3JvbGxlZCAubmF2LWxpbmtzIGF7Y29sb3I6dmFyKC0tbXV0ZWQpO30KLm5hdi1saW5rcyBhOjphZnRlcnsKICBjb250ZW50OicnO3Bvc2l0aW9uOmFic29sdXRlO2JvdHRvbTowO2xlZnQ6MDtyaWdodDoxMDAlOwogIGhlaWdodDoxcHg7YmFja2dyb3VuZDp2YXIoLS1nb2xkKTt0cmFuc2l0aW9uOnJpZ2h0IDAuM3MgZWFzZTsKfQoubmF2LWxpbmtzIGE6aG92ZXI6OmFmdGVye3JpZ2h0OjA7fQoubmF2LWxpbmtzIGE6aG92ZXJ7Y29sb3I6dmFyKC0tZ29sZCk7fQpuYXYuc2Nyb2xsZWQgLm5hdi1saW5rcyBhOmhvdmVye2NvbG9yOnZhcigtLWluayk7fQoubmF2LWJvb2t7CiAgcGFkZGluZzoxMHB4IDI4cHg7Ym9yZGVyOjFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuNik7CiAgYmFja2dyb3VuZDp0cmFuc3BhcmVudDtjb2xvcjp3aGl0ZTsKICBmb250LWZhbWlseTonSm9zdCc7Zm9udC1zaXplOjEwcHg7bGV0dGVyLXNwYWNpbmc6NHB4OwogIHRleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTtjdXJzb3I6bm9uZTt0cmFuc2l0aW9uOmFsbCAwLjNzOwp9Cm5hdi5zY3JvbGxlZCAubmF2LWJvb2t7Ym9yZGVyLWNvbG9yOnZhcigtLWdvbGQpO2NvbG9yOnZhcigtLWdvbGQpO30KLm5hdi1ib29rOmhvdmVye2JhY2tncm91bmQ6dmFyKC0tZ29sZCk7Ym9yZGVyLWNvbG9yOnZhcigtLWdvbGQpO2NvbG9yOndoaXRlO30KCi8qIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCBIRVJPIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAqLwouaGVyb3sKICBwb3NpdGlvbjpyZWxhdGl2ZTtoZWlnaHQ6MTAwdmg7bWluLWhlaWdodDo2NDBweDsKICBkaXNwbGF5OmZsZXg7YWxpZ24taXRlbXM6Y2VudGVyO2p1c3RpZnktY29udGVudDpjZW50ZXI7CiAgb3ZlcmZsb3c6aGlkZGVuOwp9Ci5oZXJvLXZpZGVvewogIHBvc2l0aW9uOmFic29sdXRlO2luc2V0OjA7d2lkdGg6MTAwJTtoZWlnaHQ6MTAwJTsKICBvYmplY3QtZml0OmNvdmVyO29iamVjdC1wb3NpdGlvbjpjZW50ZXI7Cn0KLyogTXVsdGktbGF5ZXIgb3ZlcmxheTogYm90dG9tLXVwIGRhcmsgKyB3YXJtIHRpbnQgKi8KLmhlcm8tb3ZlcmxheXsKICBwb3NpdGlvbjphYnNvbHV0ZTtpbnNldDowOwogIGJhY2tncm91bmQ6CiAgICBsaW5lYXItZ3JhZGllbnQodG8gdG9wLCByZ2JhKDI2LDE4LDgsMC44OCkgMCUsIHJnYmEoMjYsMTgsOCwwLjU1KSA0NSUsIHJnYmEoMjYsMTgsOCwwLjY1KSAxMDAlKTsKfQovKiBUaWxlLWNvbG9yIHN0cmlwZSBhdCB2ZXJ5IHRvcCDigJQgbG9nbyBhcmNoIHJlZmVyZW5jZSAqLwouaGVyby10b3Atc3RyaXBlewogIHBvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDtyaWdodDowOwogIGhlaWdodDo0cHg7ZGlzcGxheTpmbGV4O3otaW5kZXg6NTsKfQouaGVyby10b3Atc3RyaXBlIHNwYW57ZmxleDoxO30KCi8qIEhlcm8gY29udGVudCAqLwouaGVyby1jb250ZW50ewogIHBvc2l0aW9uOnJlbGF0aXZlO3otaW5kZXg6Mzt0ZXh0LWFsaWduOmNlbnRlcjsKICBwYWRkaW5nOjAgMjRweDttYXgtd2lkdGg6NzYwcHg7Cn0KLmhlcm8tZXllYnJvd3sKICBmb250LXNpemU6MTBweDtsZXR0ZXItc3BhY2luZzo4cHg7dGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlOwogIGNvbG9yOiNGNUQwN0E7bWFyZ2luLWJvdHRvbToyNHB4OwogIGRpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcjtnYXA6MjBweDsKICB0ZXh0LXNoYWRvdzowIDFweCA4cHggcmdiYSgwLDAsMCwwLjkpOwp9Ci8qIFNtYWxsIDPDlzMgdGlsZSBpY29uIGFzIGJ1bGxldCDigJQgdGhlIHRpbGUgY29uY2VwdCAqLwoudGlsZS1pY29uewogIGRpc3BsYXk6aW5saW5lLWdyaWQ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOnJlcGVhdCgzLDZweCk7Z3JpZC10ZW1wbGF0ZS1yb3dzOnJlcGVhdCgzLDZweCk7Z2FwOjFweDsKICB2ZXJ0aWNhbC1hbGlnbjptaWRkbGU7Cn0KLnRpbGUtaWNvbiBzcGFue2JvcmRlci1yYWRpdXM6MXB4O30KLmhlcm8taDF7CiAgZm9udC1mYW1pbHk6J0NpbnplbCcsc2VyaWY7CiAgZm9udC1zaXplOjgwcHg7Zm9udC13ZWlnaHQ6NDAwO2xpbmUtaGVpZ2h0OjE7CiAgY29sb3I6I2ZmZjtsZXR0ZXItc3BhY2luZzoxMHB4O21hcmdpbi1ib3R0b206MjBweDsKICBmb250LXN0eWxlOm5vcm1hbDsKICB0ZXh0LXNoYWRvdzowIDJweCAzMnB4IHJnYmEoMCwwLDAsMC43KSwwIDFweCA0cHggcmdiYSgwLDAsMCwwLjkpOwp9Ci5oZXJvLXRhZ2xpbmV7CiAgZm9udC1zaXplOjE0cHg7bGV0dGVyLXNwYWNpbmc6MnB4O2NvbG9yOnJnYmEoMjU1LDI1NSwyNTUsMC45Mik7CiAgbWFyZ2luLWJvdHRvbTo0OHB4O2xpbmUtaGVpZ2h0OjEuOTsKICB0ZXh0LXNoYWRvdzowIDFweCAxMnB4IHJnYmEoMCwwLDAsMC44KTsKICBmb250LXdlaWdodDozMDA7Cn0KLyogVGhpbiB0aWxlLXN0cmlwIGRpdmlkZXIgKi8KLmhlcm8tZGl2aWRlcnsKICB3aWR0aDoxMjBweDtoZWlnaHQ6M3B4O21hcmdpbjowIGF1dG8gNDBweDsKICBkaXNwbGF5OmZsZXg7Z2FwOjJweDsKfQouaGVyby1kaXZpZGVyIHNwYW57ZmxleDoxO2JvcmRlci1yYWRpdXM6MXB4O30KLmhlcm8tY3RhewogIGRpc3BsYXk6aW5saW5lLWZsZXg7YWxpZ24taXRlbXM6Y2VudGVyO2dhcDoxNnB4OwogIHBhZGRpbmc6MTVweCA0OHB4O2JvcmRlcjoxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjYpOwogIGNvbG9yOndoaXRlO2ZvbnQtZmFtaWx5OidKb3N0Jztmb250LXNpemU6MTBweDtsZXR0ZXItc3BhY2luZzo1cHg7CiAgdGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlO3RleHQtZGVjb3JhdGlvbjpub25lO2N1cnNvcjpub25lOwogIHRyYW5zaXRpb246YWxsIDAuMzVzO3Bvc2l0aW9uOnJlbGF0aXZlO292ZXJmbG93OmhpZGRlbjsKfQouaGVyby1jdGE6OmJlZm9yZXsKICBjb250ZW50OicnO3Bvc2l0aW9uOmFic29sdXRlO2luc2V0OjA7CiAgYmFja2dyb3VuZDp2YXIoLS1nb2xkKTt0cmFuc2Zvcm06dHJhbnNsYXRlWCgtMTAxJSk7CiAgdHJhbnNpdGlvbjp0cmFuc2Zvcm0gMC4zNXMgZWFzZTt6LWluZGV4Oi0xOwp9Ci5oZXJvLWN0YTpob3Zlcntib3JkZXItY29sb3I6dmFyKC0tZ29sZCk7bGV0dGVyLXNwYWNpbmc6NnB4O30KLmhlcm8tY3RhOmhvdmVyOjpiZWZvcmV7dHJhbnNmb3JtOnRyYW5zbGF0ZVgoMCk7fQoKLyogU2Nyb2xsIGluZGljYXRvciAqLwouc2Nyb2xsLWluZGljYXRvcnsKICBwb3NpdGlvbjphYnNvbHV0ZTtib3R0b206MzZweDtsZWZ0OjUwJTt0cmFuc2Zvcm06dHJhbnNsYXRlWCgtNTAlKTsKICBkaXNwbGF5OmZsZXg7ZmxleC1kaXJlY3Rpb246Y29sdW1uO2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6MTBweDsKICB6LWluZGV4OjM7Y3Vyc29yOm5vbmU7CiAgYW5pbWF0aW9uOmZsb2F0IDIuNXMgZWFzZS1pbi1vdXQgaW5maW5pdGU7Cn0KQGtleWZyYW1lcyBmbG9hdHswJSwxMDAle3RyYW5zZm9ybTp0cmFuc2xhdGVYKC01MCUpIHRyYW5zbGF0ZVkoMCk7fTUwJXt0cmFuc2Zvcm06dHJhbnNsYXRlWCgtNTAlKSB0cmFuc2xhdGVZKC02cHgpO319Ci5zY3JvbGwtbGluZXt3aWR0aDoxcHg7aGVpZ2h0OjUwcHg7YmFja2dyb3VuZDpsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLHRyYW5zcGFyZW50LHJnYmEoMjU1LDI1NSwyNTUsMC41KSx0cmFuc3BhcmVudCk7fQouc2Nyb2xsLXRleHR7Zm9udC1zaXplOjlweDtsZXR0ZXItc3BhY2luZzo0cHg7dGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlO2NvbG9yOnJnYmEoMjU1LDI1NSwyNTUsMC40NSk7fQoKLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIFNUQVRTIEJBTkQg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQICovCi5zdGF0cy1iYW5kewogIGJhY2tncm91bmQ6dmFyKC0taW5rKTsKICBkaXNwbGF5OmZsZXg7Cn0KLnN0YXR7CiAgZmxleDoxO3BhZGRpbmc6MzJweCAyNHB4O3RleHQtYWxpZ246Y2VudGVyOwogIGJvcmRlci1yaWdodDoxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjA2KTsKICB0cmFuc2l0aW9uOmJhY2tncm91bmQgMC4zcztjdXJzb3I6ZGVmYXVsdDsKfQouc3RhdDpsYXN0LWNoaWxke2JvcmRlci1yaWdodDpub25lO30KLnN0YXQ6aG92ZXJ7YmFja2dyb3VuZDp2YXIoLS1pbmsyKTt9Ci5zdGF0LW51bXsKICBmb250LWZhbWlseTonQ29ybW9yYW50IEdhcmFtb25kJyxzZXJpZjsKICBmb250LXNpemU6NDJweDtmb250LXdlaWdodDozMDA7Y29sb3I6dmFyKC0tZ29sZC1sdCk7bGluZS1oZWlnaHQ6MTsKfQouc3RhdC1sYWJlbHtmb250LXNpemU6OXB4O2xldHRlci1zcGFjaW5nOjRweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7Y29sb3I6cmdiYSgyNTUsMjU1LDI1NSwwLjM1KTttYXJnaW4tdG9wOjZweDt9CgovKiDilZDilZDilZDilZDilZDilZDilZDilZAgU0VDVElPTiBDT01NT04g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQICovCi5zZWN0aW9ue3BhZGRpbmc6MTAwcHggODBweDttYXgtd2lkdGg6MTI0MHB4O21hcmdpbjowIGF1dG87fQouc2VjdGlvbi1oZWFke21hcmdpbi1ib3R0b206NjRweDt9Ci5zZWN0aW9uLWV5ZWJyb3d7CiAgZm9udC1zaXplOjEwcHg7bGV0dGVyLXNwYWNpbmc6N3B4O3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTsKICBjb2xvcjp2YXIoLS1nb2xkKTttYXJnaW4tYm90dG9tOjE0cHg7CiAgZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6MTZweDsKfQouc2VjdGlvbi1leWVicm93OjphZnRlcntjb250ZW50OicnO2ZsZXg6MTttYXgtd2lkdGg6NjBweDtoZWlnaHQ6MXB4O2JhY2tncm91bmQ6dmFyKC0tYm9yZGVyKTt9Ci5zZWN0aW9uLXRpdGxlewogIGZvbnQtZmFtaWx5OidDaW56ZWwnLHNlcmlmOwogIGZvbnQtc2l6ZTo0OHB4O2ZvbnQtd2VpZ2h0OjQwMDtjb2xvcjp2YXIoLS1pbmspO2xpbmUtaGVpZ2h0OjEuMDU7bGV0dGVyLXNwYWNpbmc6M3B4Owp9Ci5zZWN0aW9uLXRpdGxlIGVte2ZvbnQtZmFtaWx5OidDaW56ZWwnLHNlcmlmO2ZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtd2VpZ2h0OjQwMDtjb2xvcjp2YXIoLS1nb2xkKTtsZXR0ZXItc3BhY2luZzozcHg7fQovKiBUaWxlIHVuZGVybGluZSBvbiBzZWN0aW9uIHRpdGxlIOKAlCB0aGUgY29uY2VwdCwgbm90IGxpdGVyYWwgdGlsZXMgKi8KLnRpdGxlLXRpbGUtbGluZXsKICB3aWR0aDo4MHB4O2hlaWdodDo0cHg7bWFyZ2luLXRvcDoyMHB4OwogIGRpc3BsYXk6ZmxleDtnYXA6MnB4Owp9Ci50aXRsZS10aWxlLWxpbmUgc3BhbntmbGV4OjE7Ym9yZGVyLXJhZGl1czoxcHg7fQoKLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIFJPT01TIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAqLwoucm9vbXMtd3JhcHtwYWRkaW5nOjEwMHB4IDAgMDtiYWNrZ3JvdW5kOnZhcigtLWNyZWFtKTt9Ci5yb29tcy1ncmlkewogIGRpc3BsYXk6Z3JpZDsKICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6MWZyIDFmciAxZnI7CiAgZ3JpZC10ZW1wbGF0ZS1yb3dzOjQyMHB4IDI4MHB4OwogIGdhcDoycHg7Cn0KLnJvb20tY2FyZHsKICBwb3NpdGlvbjpyZWxhdGl2ZTtvdmVyZmxvdzpoaWRkZW47Y3Vyc29yOm5vbmU7CiAgYmFja2dyb3VuZDp2YXIoLS1pbmspOwp9Ci5yb29tLWNhcmQuaGVyby1jYXJke2dyaWQtY29sdW1uOnNwYW4gMjt9CgovKiBBY3R1YWwgcm9vbSBwaG90byAqLwoucm9vbS1waG90b3sKICBwb3NpdGlvbjphYnNvbHV0ZTtpbnNldDowO3dpZHRoOjEwMCU7aGVpZ2h0OjEwMCU7CiAgb2JqZWN0LWZpdDpjb3ZlcjtvYmplY3QtcG9zaXRpb246Y2VudGVyOwogIHRyYW5zaXRpb246dHJhbnNmb3JtIDAuNnMgY3ViaWMtYmV6aWVyKDAuMjUsMC40NiwwLjQ1LDAuOTQpOwp9Ci5yb29tLWNhcmQ6aG92ZXIgLnJvb20tcGhvdG97dHJhbnNmb3JtOnNjYWxlKDEuMDYpO30KCi8qIERhcmsgYm90dG9tIG92ZXJsYXkgKi8KLnJvb20tb3ZlcmxheXsKICBwb3NpdGlvbjphYnNvbHV0ZTtpbnNldDowOwogIGJhY2tncm91bmQ6bGluZWFyLWdyYWRpZW50KHRvIHRvcCxyZ2JhKDI2LDE4LDgsMC45KSAwJSxyZ2JhKDI2LDE4LDgsMC4xNSkgNTUlLHRyYW5zcGFyZW50IDEwMCUpOwogIGRpc3BsYXk6ZmxleDtmbGV4LWRpcmVjdGlvbjpjb2x1bW47anVzdGlmeS1jb250ZW50OmZsZXgtZW5kO3BhZGRpbmc6MzJweDsKICB0cmFuc2l0aW9uOmJhY2tncm91bmQgMC40czsKfQoucm9vbS1jYXJkOmhvdmVyIC5yb29tLW92ZXJsYXl7YmFja2dyb3VuZDpsaW5lYXItZ3JhZGllbnQodG8gdG9wLHJnYmEoMjYsMTgsOCwwLjk1KSAwJSxyZ2JhKDI2LDE4LDgsMC40KSA2NSUscmdiYSgyMDAsMTM0LDEwLDAuMDUpIDEwMCUpO30KCi8qIFRpbGUtY29sb3VyIGFjY2VudCB0b3AgYm9yZGVyIOKAlCBhcHBlYXJzIG9uIGhvdmVyICovCi5yb29tLXRvcC1hY2NlbnR7CiAgcG9zaXRpb246YWJzb2x1dGU7dG9wOjA7bGVmdDowO3JpZ2h0OjA7aGVpZ2h0OjRweDsKICBkaXNwbGF5OmZsZXg7Z2FwOjFweDsKICB0cmFuc2Zvcm06c2NhbGVYKDApO3RyYW5zZm9ybS1vcmlnaW46bGVmdDsKICB0cmFuc2l0aW9uOnRyYW5zZm9ybSAwLjQ1cyBjdWJpYy1iZXppZXIoMC4yNSwwLjQ2LDAuNDUsMC45NCk7Cn0KLnJvb20tY2FyZDpob3ZlciAucm9vbS10b3AtYWNjZW50e3RyYW5zZm9ybTpzY2FsZVgoMSk7fQoucm9vbS10b3AtYWNjZW50IHNwYW57ZmxleDoxO30KCi5yb29tLXRhZ3tmb250LXNpemU6OXB4O2xldHRlci1zcGFjaW5nOjRweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7Y29sb3I6dmFyKC0tZ29sZC1sdCk7bWFyZ2luLWJvdHRvbTo4cHg7fQoucm9vbS1uYW1lewogIGZvbnQtZmFtaWx5OidDb3Jtb3JhbnQgR2FyYW1vbmQnLHNlcmlmOwogIGZvbnQtc2l6ZTozMnB4O2ZvbnQtd2VpZ2h0OjMwMDtjb2xvcjp3aGl0ZTtsaW5lLWhlaWdodDoxOwp9Ci5yb29tLWNhcmQuaGVyby1jYXJkIC5yb29tLW5hbWV7Zm9udC1zaXplOjQycHg7fQoucm9vbS1tZXRhewogIGZvbnQtc2l6ZToxMXB4O2NvbG9yOnJnYmEoMjU1LDI1NSwyNTUsMC41KTttYXJnaW4tdG9wOjhweDsKICBtYXgtaGVpZ2h0OjA7b3ZlcmZsb3c6aGlkZGVuOwogIHRyYW5zaXRpb246bWF4LWhlaWdodCAwLjRzIGVhc2Usb3BhY2l0eSAwLjNzOwogIG9wYWNpdHk6MDsKfQoucm9vbS1jYXJkOmhvdmVyIC5yb29tLW1ldGF7bWF4LWhlaWdodDo0MHB4O29wYWNpdHk6MTt9Ci5yb29tLXByaWNlLXRhZ3sKICBwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MjRweDtyaWdodDoyNHB4OwogIGJhY2tncm91bmQ6cmdiYSgxNSwxMCw2LDAuNyk7YmFja2Ryb3AtZmlsdGVyOmJsdXIoOHB4KTsKICBib3JkZXI6MXB4IHNvbGlkIHJnYmEoMjAwLDEzNCwxMCwwLjQpOwogIHBhZGRpbmc6OHB4IDE2cHg7Y29sb3I6dmFyKC0tZ29sZC1sdCk7Zm9udC1zaXplOjExcHg7bGV0dGVyLXNwYWNpbmc6MXB4OwogIG9wYWNpdHk6MDt0cmFuc2Zvcm06dHJhbnNsYXRlWSgtNnB4KTsKICB0cmFuc2l0aW9uOm9wYWNpdHkgMC4zcyx0cmFuc2Zvcm0gMC4zczsKfQoucm9vbS1jYXJkOmhvdmVyIC5yb29tLXByaWNlLXRhZ3tvcGFjaXR5OjE7dHJhbnNmb3JtOnRyYW5zbGF0ZVkoMCk7fQoKLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIFBISUxPU09QSFkgU1RSSVAg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQICovCi5waGlsb3NvcGh5ewogIGJhY2tncm91bmQ6dmFyKC0tcGFyY2gpOwogIGJvcmRlci10b3A6MXB4IHNvbGlkIHZhcigtLWJvcmRlcik7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBwYWRkaW5nOjgwcHg7CiAgcG9zaXRpb246cmVsYXRpdmU7b3ZlcmZsb3c6aGlkZGVuOwp9Ci8qIFN1YnRsZSB0aWxlIHBhdHRlcm4gaW4gYmFja2dyb3VuZCDigJQgVkVSWSBmYWludCwganVzdCB0ZXh0dXJlICovCi5waGlsb3NvcGh5OjpiZWZvcmV7CiAgY29udGVudDonJztwb3NpdGlvbjphYnNvbHV0ZTtpbnNldDowOwogIGJhY2tncm91bmQtaW1hZ2U6CiAgICByZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KDBkZWcsdHJhbnNwYXJlbnQsdHJhbnNwYXJlbnQgMzlweCxyZ2JhKDIwMCwxMzQsMTAsMC4wNCkgMzlweCxyZ2JhKDIwMCwxMzQsMTAsMC4wNCkgNDBweCksCiAgICByZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KDkwZGVnLHRyYW5zcGFyZW50LHRyYW5zcGFyZW50IDM5cHgscmdiYSgyMDAsMTM0LDEwLDAuMDQpIDM5cHgscmdiYSgyMDAsMTM0LDEwLDAuMDQpIDQwcHgpOwogIHBvaW50ZXItZXZlbnRzOm5vbmU7Cn0KLnBoaWxvc29waHktaW5uZXJ7CiAgcG9zaXRpb246cmVsYXRpdmU7ei1pbmRleDoxOwogIGRpc3BsYXk6Z3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6MWZyIDFmciAxZnI7CiAgZ2FwOjA7bWF4LXdpZHRoOjEwMDBweDttYXJnaW46MCBhdXRvOwp9Ci5waGlsLWNvbHsKICBwYWRkaW5nOjQwcHggNDhweDsKICBib3JkZXItcmlnaHQ6MXB4IHNvbGlkIHZhcigtLWJvcmRlcik7CiAgdGV4dC1hbGlnbjpjZW50ZXI7Cn0KLnBoaWwtY29sOmxhc3QtY2hpbGR7Ym9yZGVyLXJpZ2h0Om5vbmU7fQovKiBTbWFsbCB0aWxlIGljb24g4oCUIHRoZSBjb25jZXB0LCB0YXN0ZWZ1bCAqLwoucGhpbC10aWxlLWljb257CiAgZGlzcGxheTppbmxpbmUtZ3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6cmVwZWF0KDQsMTBweCk7Z3JpZC10ZW1wbGF0ZS1yb3dzOnJlcGVhdCg0LDEwcHgpO2dhcDoycHg7CiAgbWFyZ2luLWJvdHRvbToyNHB4Owp9Ci5waGlsLXRpbGUtaWNvbiBzcGFue2JvcmRlci1yYWRpdXM6MnB4O30KLnBoaWwtdGl0bGV7CiAgZm9udC1mYW1pbHk6J0Nvcm1vcmFudCBHYXJhbW9uZCcsc2VyaWY7CiAgZm9udC1zaXplOjI0cHg7Zm9udC13ZWlnaHQ6MzAwO2NvbG9yOnZhcigtLWluayk7bWFyZ2luLWJvdHRvbToxNHB4Owp9Ci5waGlsLWJvZHl7Zm9udC1zaXplOjEzcHg7Y29sb3I6dmFyKC0tbXV0ZWQpO2xpbmUtaGVpZ2h0OjEuODU7bGV0dGVyLXNwYWNpbmc6MC4ycHg7fQoKLyog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIEZVTEwtQkxFRUQgRVhQRVJJRU5DRSDilZDilZDilZDilZDilZDilZDilZDilZAgKi8KLmV4cGVyaWVuY2V7CiAgcG9zaXRpb246cmVsYXRpdmU7aGVpZ2h0OjUyMHB4OwogIGRpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7b3ZlcmZsb3c6aGlkZGVuOwp9Ci5leHAtcGhvdG97CiAgcG9zaXRpb246YWJzb2x1dGU7aW5zZXQ6MDt3aWR0aDoxMDAlO2hlaWdodDoxMDAlOwogIG9iamVjdC1maXQ6Y292ZXI7CiAgdHJhbnNpdGlvbjp0cmFuc2Zvcm0gMC4xcyBsaW5lYXI7LyogcGFyYWxsYXggdmlhIEpTICovCn0KLmV4cC1vdmVybGF5ewogIHBvc2l0aW9uOmFic29sdXRlO2luc2V0OjA7CiAgYmFja2dyb3VuZDpsaW5lYXItZ3JhZGllbnQoOTBkZWcscmdiYSgyNiwxOCw4LDAuODgpIDAlLHJnYmEoMjYsMTgsOCwwLjU1KSA1MCUsdHJhbnNwYXJlbnQgMTAwJSk7Cn0KLmV4cC1jb250ZW50ewogIHBvc2l0aW9uOnJlbGF0aXZlO3otaW5kZXg6MjsKICBwYWRkaW5nOjAgMTAwcHg7bWF4LXdpZHRoOjU2MHB4Owp9Ci5leHAtZXllYnJvd3tmb250LXNpemU6MTBweDtsZXR0ZXItc3BhY2luZzo2cHg7dGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlO2NvbG9yOnZhcigtLWdvbGQtbHQpO21hcmdpbi1ib3R0b206MjBweDt9Ci5leHAtdGl0bGV7CiAgZm9udC1mYW1pbHk6J0Nvcm1vcmFudCBHYXJhbW9uZCcsc2VyaWY7CiAgZm9udC1zaXplOjUycHg7Zm9udC13ZWlnaHQ6MzAwO2NvbG9yOndoaXRlO2xpbmUtaGVpZ2h0OjE7bWFyZ2luLWJvdHRvbToyMHB4Owp9Ci5leHAtdGl0bGUgZW17Zm9udC1zdHlsZTpub3JtYWw7Y29sb3I6dmFyKC0tZ29sZC1sdCk7fQouZXhwLWJvZHl7Zm9udC1zaXplOjE0cHg7Y29sb3I6cmdiYSgyNTUsMjU1LDI1NSwwLjYpO2xpbmUtaGVpZ2h0OjEuODttYXJnaW4tYm90dG9tOjM2cHg7fQouZXhwLXRpbGUtc3RyaXB7d2lkdGg6MTAwJTtoZWlnaHQ6NHB4O2Rpc3BsYXk6ZmxleDtnYXA6MnB4O21hcmdpbi1ib3R0b206MjhweDt9Ci5leHAtdGlsZS1zdHJpcCBzcGFue2ZsZXg6MTtib3JkZXItcmFkaXVzOjFweDt9Ci5idG4tbGlnaHR7CiAgZGlzcGxheTppbmxpbmUtYmxvY2s7cGFkZGluZzoxM3B4IDQwcHg7CiAgYm9yZGVyOjFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuNSk7Y29sb3I6d2hpdGU7CiAgZm9udC1mYW1pbHk6J0pvc3QnO2ZvbnQtc2l6ZToxMHB4O2xldHRlci1zcGFjaW5nOjRweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7CiAgdGV4dC1kZWNvcmF0aW9uOm5vbmU7Y3Vyc29yOm5vbmU7dHJhbnNpdGlvbjphbGwgMC4zczsKfQouYnRuLWxpZ2h0OmhvdmVye2JhY2tncm91bmQ6d2hpdGU7Y29sb3I6dmFyKC0taW5rKTt9CgovKiDilZDilZDilZDilZDilZDilZDilZDilZAgR0FMTEVSWSDilZDilZDilZDilZDilZDilZDilZDilZAgKi8KLmdhbGxlcnl7ZGlzcGxheTpmbGV4O2dhcDoycHg7aGVpZ2h0OjM4MHB4O30KLmdhbC1pdGVtewogIGZsZXg6MTttaW4td2lkdGg6MDtwb3NpdGlvbjpyZWxhdGl2ZTtvdmVyZmxvdzpoaWRkZW47Y3Vyc29yOm5vbmU7CiAgdHJhbnNpdGlvbjpmbGV4IDAuNXMgY3ViaWMtYmV6aWVyKDAuMjUsMC40NiwwLjQ1LDAuOTQpOwp9Ci5nYWwtaXRlbTpob3ZlcntmbGV4OjMuNTt9Ci5nYWwtcGhvdG97CiAgcG9zaXRpb246YWJzb2x1dGU7aW5zZXQ6MDt3aWR0aDoxMDAlO2hlaWdodDoxMDAlOwogIG9iamVjdC1maXQ6Y292ZXI7dHJhbnNpdGlvbjp0cmFuc2Zvcm0gMC41czsKfQouZ2FsLWl0ZW06aG92ZXIgLmdhbC1waG90b3t0cmFuc2Zvcm06c2NhbGUoMS4wNCk7fQouZ2FsLW92ZXJsYXl7CiAgcG9zaXRpb246YWJzb2x1dGU7aW5zZXQ6MDsKICBiYWNrZ3JvdW5kOmxpbmVhci1ncmFkaWVudCh0byB0b3AscmdiYSgyNiwxOCw4LDAuNzUpIDAlLHRyYW5zcGFyZW50IDYwJSk7CiAgb3BhY2l0eTowO3RyYW5zaXRpb246b3BhY2l0eSAwLjRzOwp9Ci5nYWwtaXRlbTpob3ZlciAuZ2FsLW92ZXJsYXl7b3BhY2l0eToxO30KLmdhbC1sYWJlbHsKICBwb3NpdGlvbjphYnNvbHV0ZTtib3R0b206MjRweDtsZWZ0OjI0cHg7CiAgZm9udC1mYW1pbHk6J0Nvcm1vcmFudCBHYXJhbW9uZCcsc2VyaWY7CiAgZm9udC1zaXplOjI2cHg7Zm9udC1zdHlsZTpub3JtYWw7Y29sb3I6d2hpdGU7CiAgb3BhY2l0eTowO3RyYW5zZm9ybTp0cmFuc2xhdGVZKDEwcHgpOwogIHRyYW5zaXRpb246YWxsIDAuMzVzIDAuMDVzOwp9Ci5nYWwtaXRlbTpob3ZlciAuZ2FsLWxhYmVse29wYWNpdHk6MTt0cmFuc2Zvcm06dHJhbnNsYXRlWSgwKTt9Ci8qIFRpbGUtY29sb3IgbGVmdCBib3JkZXIgb24gaG92ZXIgKi8KLmdhbC1pdGVtOjphZnRlcnsKICBjb250ZW50OicnO3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDtib3R0b206MDt3aWR0aDo0cHg7CiAgYmFja2dyb3VuZDpsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLHZhcigtLWdvbGQpLHZhcigtLXRlYWwpLHZhcigtLWJ1cmcpKTsKICB0cmFuc2Zvcm06c2NhbGVZKDApO3RyYW5zZm9ybS1vcmlnaW46dG9wOwogIHRyYW5zaXRpb246dHJhbnNmb3JtIDAuNHMgZWFzZTt6LWluZGV4OjM7Cn0KLmdhbC1pdGVtOmhvdmVyOjphZnRlcnt0cmFuc2Zvcm06c2NhbGVZKDEpO30KCi8qIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCBURVNUSU1PTklBTFMg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQICovCi50ZXN0aS13cmFwe3BhZGRpbmc6MTAwcHggODBweDtiYWNrZ3JvdW5kOnZhcigtLWNyZWFtKTt9Ci50ZXN0aS1ncmlke2Rpc3BsYXk6Z3JpZDtncmlkLXRlbXBsYXRlLWNvbHVtbnM6cmVwZWF0KDMsMWZyKTtnYXA6MjhweDttYXJnaW4tdG9wOjY0cHg7fQoudGVzdGktY2FyZHsKICBiYWNrZ3JvdW5kOndoaXRlO3BhZGRpbmc6NDBweCAzNnB4OwogIGJvcmRlcjoxcHggc29saWQgdmFyKC0tYm9yZGVyKTsKICBwb3NpdGlvbjpyZWxhdGl2ZTt0cmFuc2l0aW9uOnRyYW5zZm9ybSAwLjNzLGJveC1zaGFkb3cgMC4zcztjdXJzb3I6ZGVmYXVsdDsKfQoudGVzdGktY2FyZDpob3Zlcnt0cmFuc2Zvcm06dHJhbnNsYXRlWSgtNHB4KTtib3gtc2hhZG93OjAgMTJweCA0MHB4IHJnYmEoMjAwLDEzNCwxMCwwLjEpO30KLyogVGlsZS1jb2xvciB0b3AgYWNjZW50IGJhciAqLwoudGVzdGktYWNjZW50ewogIHBvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDtyaWdodDowO2hlaWdodDo0cHg7CiAgZGlzcGxheTpmbGV4O2dhcDoxcHg7b3ZlcmZsb3c6aGlkZGVuOwp9Ci50ZXN0aS1hY2NlbnQgc3BhbntmbGV4OjE7fQoudGVzdGktcXVvdGV7CiAgZm9udC1mYW1pbHk6J0Nvcm1vcmFudCBHYXJhbW9uZCcsc2VyaWY7CiAgZm9udC1zaXplOjE4cHg7Zm9udC1zdHlsZTpub3JtYWw7Y29sb3I6dmFyKC0taW5rKTsKICBsaW5lLWhlaWdodDoxLjc1O21hcmdpbi1ib3R0b206MjhweDsKfQoudGVzdGktbmFtZXtmb250LXNpemU6MTBweDtsZXR0ZXItc3BhY2luZzozcHg7dGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlO2NvbG9yOnZhcigtLW11dGVkKTt9Ci8qIERlY29yYXRpdmUgcXVvdGUgbWFyayAqLwoudGVzdGktY2FyZDo6YmVmb3JlewogIGNvbnRlbnQ6J1wyMDFDJzsKICBmb250LWZhbWlseTonQ29ybW9yYW50IEdhcmFtb25kJyxzZXJpZjsKICBmb250LXNpemU6MTIwcHg7Y29sb3I6dmFyKC0tZ29sZCk7b3BhY2l0eTowLjA3OwogIHBvc2l0aW9uOmFic29sdXRlO3RvcDotMTBweDtsZWZ0OjIwcHg7bGluZS1oZWlnaHQ6MTsKICBwb2ludGVyLWV2ZW50czpub25lOwp9CgovKiDilZDilZDilZDilZDilZDilZDilZDilZAgQk9PS0lORyDilZDilZDilZDilZDilZDilZDilZDilZAgKi8KLmJvb2tpbmd7CiAgYmFja2dyb3VuZDp2YXIoLS1pbmspO3BhZGRpbmc6MTAwcHggODBweDsKICB0ZXh0LWFsaWduOmNlbnRlcjtwb3NpdGlvbjpyZWxhdGl2ZTtvdmVyZmxvdzpoaWRkZW47Cn0KLyogU3VidGxlIHRpbGUgZ3JpZCB0ZXh0dXJlIGluIGJnICovCi5ib29raW5nOjpiZWZvcmV7CiAgY29udGVudDonJztwb3NpdGlvbjphYnNvbHV0ZTtpbnNldDowOwogIGJhY2tncm91bmQtaW1hZ2U6CiAgICByZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KDBkZWcsdHJhbnNwYXJlbnQsdHJhbnNwYXJlbnQgNDlweCxyZ2JhKDIwMCwxMzQsMTAsMC4wNCkgNDlweCxyZ2JhKDIwMCwxMzQsMTAsMC4wNCkgNTBweCksCiAgICByZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KDkwZGVnLHRyYW5zcGFyZW50LHRyYW5zcGFyZW50IDQ5cHgscmdiYSgyMDAsMTM0LDEwLDAuMDQpIDQ5cHgscmdiYSgyMDAsMTM0LDEwLDAuMDQpIDUwcHgpOwogIHBvaW50ZXItZXZlbnRzOm5vbmU7Cn0KLyogUmFpbmJvdyB0aWxlIHN0cmlwZSBhdCB0b3AgKi8KLmJvb2tpbmctc3RyaXBle3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDtyaWdodDowO2hlaWdodDo1cHg7ZGlzcGxheTpmbGV4O30KLmJvb2tpbmctc3RyaXBlIHNwYW57ZmxleDoxO30KLmJvb2tpbmctY29udGVudHtwb3NpdGlvbjpyZWxhdGl2ZTt6LWluZGV4OjE7fQouYm9va2luZy1leWVicm93e2ZvbnQtc2l6ZToxMHB4O2xldHRlci1zcGFjaW5nOjdweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7Y29sb3I6dmFyKC0tZ29sZCk7bWFyZ2luLWJvdHRvbToyMHB4O30KLmJvb2tpbmctdGl0bGV7CiAgZm9udC1mYW1pbHk6J0Nvcm1vcmFudCBHYXJhbW9uZCcsc2VyaWY7CiAgZm9udC1zaXplOjYycHg7Zm9udC13ZWlnaHQ6MzAwO2NvbG9yOndoaXRlO21hcmdpbi1ib3R0b206MTZweDtsaW5lLWhlaWdodDoxOwp9Ci5ib29raW5nLXRpdGxlIHNwYW57Zm9udC1zdHlsZTpub3JtYWw7Y29sb3I6dmFyKC0tZ29sZC1sdCk7fQouYm9va2luZy1zdWJ7Zm9udC1zaXplOjEycHg7bGV0dGVyLXNwYWNpbmc6NHB4O2NvbG9yOnJnYmEoMjU1LDI1NSwyNTUsMC4zNSk7dGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlO21hcmdpbi1ib3R0b206NTJweDt9Ci5ib29raW5nLWJ0bnN7ZGlzcGxheTpmbGV4O2dhcDoxNnB4O2p1c3RpZnktY29udGVudDpjZW50ZXI7YWxpZ24taXRlbXM6Y2VudGVyO30KLmJ0bi1nb2xkewogIHBhZGRpbmc6MTZweCA1NnB4O2JhY2tncm91bmQ6dmFyKC0tZ29sZCk7Y29sb3I6d2hpdGU7CiAgZm9udC1mYW1pbHk6J0pvc3QnO2ZvbnQtc2l6ZToxMHB4O2xldHRlci1zcGFjaW5nOjVweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7CiAgYm9yZGVyOm5vbmU7Y3Vyc29yOm5vbmU7dGV4dC1kZWNvcmF0aW9uOm5vbmU7ZGlzcGxheTppbmxpbmUtYmxvY2s7CiAgdHJhbnNpdGlvbjpiYWNrZ3JvdW5kIDAuM3MsdHJhbnNmb3JtIDAuMnM7Cn0KLmJ0bi1nb2xkOmhvdmVye2JhY2tncm91bmQ6I0EwNkUwODt0cmFuc2Zvcm06dHJhbnNsYXRlWSgtMnB4KTt9Ci5idG4tb3V0bGluZS1saWdodHsKICBwYWRkaW5nOjE2cHggNDBweDsKICBib3JkZXI6MXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC4zKTtjb2xvcjpyZ2JhKDI1NSwyNTUsMjU1LDAuNyk7CiAgZm9udC1mYW1pbHk6J0pvc3QnO2ZvbnQtc2l6ZToxMHB4O2xldHRlci1zcGFjaW5nOjRweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7CiAgdGV4dC1kZWNvcmF0aW9uOm5vbmU7ZGlzcGxheTppbmxpbmUtYmxvY2s7Y3Vyc29yOm5vbmU7CiAgdHJhbnNpdGlvbjphbGwgMC4zczsKfQouYnRuLW91dGxpbmUtbGlnaHQ6aG92ZXJ7Ym9yZGVyLWNvbG9yOndoaXRlO2NvbG9yOndoaXRlO30KCi8qIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCBGT09URVIg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQICovCmZvb3RlcntiYWNrZ3JvdW5kOnZhcigtLWluazIpO3BhZGRpbmc6NjRweCA4MHB4IDMycHg7fQouZm9vdGVyLXRvcHtkaXNwbGF5OmdyaWQ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjIuNWZyIDFmciAxZnIgMWZyO2dhcDo1NnB4O21hcmdpbi1ib3R0b206NTZweDt9Ci5mb290ZXItbG9nbyBpbWd7aGVpZ2h0OjExMHB4O3dpZHRoOmF1dG87ZmlsdGVyOmJyaWdodG5lc3MoMCkgaW52ZXJ0KDEpO29wYWNpdHk6MC45O21hcmdpbi1ib3R0b206MTZweDt9Ci5mb290ZXItdGFnbGluZXtmb250LXNpemU6MTJweDtjb2xvcjpyZ2JhKDI1NSwyNTUsMjU1LDAuMyk7bGluZS1oZWlnaHQ6MS44O21heC13aWR0aDoyNjBweDt9Ci5mb290ZXItaGVhZGluZ3tmb250LXNpemU6OXB4O2xldHRlci1zcGFjaW5nOjVweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7Y29sb3I6dmFyKC0tZ29sZCk7bWFyZ2luLWJvdHRvbToyMnB4O30KLmZvb3Rlci1saW5rc3tkaXNwbGF5OmZsZXg7ZmxleC1kaXJlY3Rpb246Y29sdW1uO2dhcDoxMnB4O30KLmZvb3Rlci1saW5rcyBhe2ZvbnQtc2l6ZToxMnB4O2NvbG9yOnJnYmEoMjU1LDI1NSwyNTUsMC40KTt0ZXh0LWRlY29yYXRpb246bm9uZTt0cmFuc2l0aW9uOmNvbG9yIDAuMnM7bGV0dGVyLXNwYWNpbmc6MC41cHg7fQouZm9vdGVyLWxpbmtzIGE6aG92ZXJ7Y29sb3I6d2hpdGU7fQouZm9vdGVyLWJvdHRvbXsKICBib3JkZXItdG9wOjFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMDcpO3BhZGRpbmctdG9wOjI0cHg7CiAgZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpzcGFjZS1iZXR3ZWVuO2FsaWduLWl0ZW1zOmNlbnRlcjsKfQouZm9vdGVyLWNvcHl7Zm9udC1zaXplOjExcHg7Y29sb3I6cmdiYSgyNTUsMjU1LDI1NSwwLjIpO2xldHRlci1zcGFjaW5nOjFweDt9Ci5mb290ZXItdGlsZS1zdHJpcHtkaXNwbGF5OmZsZXg7Z2FwOjJweDt3aWR0aDo4MHB4O2hlaWdodDo0cHg7fQouZm9vdGVyLXRpbGUtc3RyaXAgc3BhbntmbGV4OjE7Ym9yZGVyLXJhZGl1czoxcHg7fQoKCgovKiDilIDilIAgUkVTUE9OU0lWRSDilIDilIAgKi8KQG1lZGlhKGhvdmVyOm5vbmUpLChwb2ludGVyOmNvYXJzZSl7Ym9keXtjdXJzb3I6YXV0bzt9I2N1cnNvciwjY3Vyc29yLXJpbmd7ZGlzcGxheTpub25lIWltcG9ydGFudDt9YSxidXR0b257Y3Vyc29yOnBvaW50ZXIhaW1wb3J0YW50O319Ci5uYXYtaGFtYnVyZ2Vye2Rpc3BsYXk6bm9uZTtmbGV4LWRpcmVjdGlvbjpjb2x1bW47anVzdGlmeS1jb250ZW50OmNlbnRlcjtnYXA6NXB4O3BhZGRpbmc6MTBweDtiYWNrZ3JvdW5kOm5vbmU7Ym9yZGVyOm5vbmU7Y3Vyc29yOnBvaW50ZXI7ei1pbmRleDoxMDAwMTtmbGV4LXNocmluazowO30KLm5hdi1oYW1idXJnZXIgc3BhbntkaXNwbGF5OmJsb2NrO3dpZHRoOjIycHg7aGVpZ2h0OjEuNXB4O2JhY2tncm91bmQ6dmFyKC0taW5rKTt0cmFuc2l0aW9uOnRyYW5zZm9ybSAuM3Msb3BhY2l0eSAuM3M7fQoubmF2LWhhbWJ1cmdlci5vcGVuIHNwYW46bnRoLWNoaWxkKDEpe3RyYW5zZm9ybTpyb3RhdGUoNDVkZWcpIHRyYW5zbGF0ZSg0LjVweCw0LjVweCk7fQoubmF2LWhhbWJ1cmdlci5vcGVuIHNwYW46bnRoLWNoaWxkKDIpe29wYWNpdHk6MDt0cmFuc2Zvcm06dHJhbnNsYXRlWCgtMTBweCk7fQoubmF2LWhhbWJ1cmdlci5vcGVuIHNwYW46bnRoLWNoaWxkKDMpe3RyYW5zZm9ybTpyb3RhdGUoLTQ1ZGVnKSB0cmFuc2xhdGUoNC41cHgsLTQuNXB4KTt9CkBtZWRpYShtYXgtd2lkdGg6MTAyNHB4KXsKICBuYXZ7cGFkZGluZzowIDMycHg7aGVpZ2h0OjgwcHg7anVzdGlmeS1jb250ZW50OmZsZXgtc3RhcnQ7fQogIC5uYXYtbG9nbyBpbWd7aGVpZ2h0OjcycHg7fQogIC5uYXYtbGlua3N7ZGlzcGxheTpub25lO3Bvc2l0aW9uOmZpeGVkO3RvcDo4MHB4O2xlZnQ6MDtyaWdodDowO2JvdHRvbTowO3otaW5kZXg6OTk5ODtiYWNrZ3JvdW5kOnJnYmEoMjUwLDI0NCwyMzQsMC45OSk7ZmxleC1kaXJlY3Rpb246Y29sdW1uO2FsaWduLWl0ZW1zOmNlbnRlcjtqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyO2dhcDozMnB4O2JhY2tkcm9wLWZpbHRlcjpub25lOy13ZWJraXQtYmFja2Ryb3AtZmlsdGVyOm5vbmU7fQogIC5uYXYtbGlua3Mub3BlbntkaXNwbGF5OmZsZXg7fQogIC5uYXYtbGlua3MgYXtmb250LXNpemU6MTNweCFpbXBvcnRhbnQ7bGV0dGVyLXNwYWNpbmc6NHB4O2NvbG9yOnZhcigtLWluaykhaW1wb3J0YW50O3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTt9CiAgLm5hdi1oYW1idXJnZXJ7bWFyZ2luLWxlZnQ6YXV0bztkaXNwbGF5OmZsZXg7fQogIC5uYXYtYm9va3tmb250LXNpemU6OXB4IWltcG9ydGFudDtwYWRkaW5nOjhweCAxNHB4IWltcG9ydGFudDtsZXR0ZXItc3BhY2luZzozcHg7fQp9CkBtZWRpYShtYXgtd2lkdGg6NzY3cHgpewogIG5hdnsKICAgIHBhZGRpbmc6MCAxNnB4O2hlaWdodDo2MHB4OwogICAgYmFja2dyb3VuZDpyZ2JhKDI1MCwyNDQsMjM0LDAuOTkpIWltcG9ydGFudDsKICAgIGJhY2tkcm9wLWZpbHRlcjpub25lIWltcG9ydGFudDstd2Via2l0LWJhY2tkcm9wLWZpbHRlcjpub25lIWltcG9ydGFudDsKICAgIGJvcmRlci1ib3R0b206MXB4IHNvbGlkIHJnYmEoMjAwLDEzNCwxMCwwLjE1KSFpbXBvcnRhbnQ7CiAgICB0cmFuc2Zvcm06dHJhbnNsYXRlWigwKTstd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGVaKDApOwogIH0KICAubmF2LWxvZ28gaW1ne2hlaWdodDo1MnB4O30KICAubmF2LWxpbmtze3RvcDo2MHB4O30KfQoubmF2LWhhbWJ1cmdlciBzcGFue2JhY2tncm91bmQ6d2hpdGU7fQpuYXYuc2Nyb2xsZWQgLm5hdi1oYW1idXJnZXIgc3BhbntiYWNrZ3JvdW5kOnZhcigtLWluayk7fQpAbWVkaWEobWF4LXdpZHRoOjc2N3B4KXsubmF2LWhhbWJ1cmdlciBzcGFue2JhY2tncm91bmQ6dmFyKC0taW5rKTt9fQpAbWVkaWEobWF4LXdpZHRoOjEwMjRweCl7CiAgLmhlcm8taDF7Zm9udC1zaXplOjU0cHg7bGV0dGVyLXNwYWNpbmc6NXB4O30KICAuc2VjdGlvbntwYWRkaW5nOjYwcHggNDBweDt9CiAgLnJvb21zLWdyaWR7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmciAxZnI7Z3JpZC10ZW1wbGF0ZS1yb3dzOmF1dG87fQogIC5yb29tLWNhcmQuaGVyby1jYXJke2dyaWQtY29sdW1uOnNwYW4gMjt9LnJvb20tY2FyZHttaW4taGVpZ2h0OjI0MHB4O30KICAucGhpbG9zb3BoeXtwYWRkaW5nOjYwcHggNDBweDt9CiAgLnRlc3RpLWdyaWR7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmciAxZnI7Z2FwOjIwcHg7fQogIC50ZXN0aS13cmFwe3BhZGRpbmc6NjBweCA0MHB4O30KICAuZm9vdGVyLXRvcHtncmlkLXRlbXBsYXRlLWNvbHVtbnM6MWZyIDFmcjtnYXA6NDBweDt9CiAgLmJvb2tpbmd7cGFkZGluZzo2MHB4IDQwcHg7fQp9CkBtZWRpYShtYXgtd2lkdGg6NzY3cHgpewogIC5oZXJvLWgxe2ZvbnQtc2l6ZTozNHB4O2xldHRlci1zcGFjaW5nOjNweDt9CiAgLmhlcm8tdGFnbGluZXtmb250LXNpemU6MTNweDttYXJnaW4tYm90dG9tOjI4cHg7fQogIC5zdGF0LW51bXtmb250LXNpemU6MzBweDt9LnN0YXRzLWJhbmR7ZmxleC13cmFwOndyYXA7fS5zdGF0e2ZsZXg6MSAxIDUwJTt9CiAgLnNlY3Rpb257cGFkZGluZzo0OHB4IDE2cHg7fQogIC5yb29tcy1ncmlke2dyaWQtdGVtcGxhdGUtY29sdW1uczoxZnI7Z3JpZC10ZW1wbGF0ZS1yb3dzOmF1dG87fQogIC5yb29tLWNhcmQuaGVyby1jYXJke2dyaWQtY29sdW1uOnNwYW4gMTt9LnJvb20tY2FyZHttaW4taGVpZ2h0OjIyMHB4O30KICAucGhpbG9zb3BoeXtwYWRkaW5nOjQwcHggMTZweDt9LnBoaWxvc29waHktaW5uZXJ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmcjt9CiAgLnBoaWwtY29se2JvcmRlci1yaWdodDpub25lO2JvcmRlci1ib3R0b206MXB4IHNvbGlkIHZhcigtLWJvcmRlcik7cGFkZGluZzoyNHB4IDE2cHg7fQogIC5waGlsLWNvbDpsYXN0LWNoaWxke2JvcmRlci1ib3R0b206bm9uZTt9CiAgLmdhbGxlcnl7ZmxleC1kaXJlY3Rpb246Y29sdW1uO2hlaWdodDphdXRvO30KICAuZ2FsLWl0ZW17ZmxleDpub25lO2hlaWdodDoxOTBweDt9LmdhbC1pdGVtOmhvdmVye2ZsZXg6bm9uZTt9CiAgLnRlc3RpLWdyaWR7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmcjt9LnRlc3RpLXdyYXB7cGFkZGluZzo0OHB4IDE2cHg7fQogIC5ib29raW5ne3BhZGRpbmc6NDhweCAxNnB4O30uYm9va2luZy10aXRsZXtmb250LXNpemU6MzRweDt9CiAgLmJvb2tpbmctYnRuc3tmbGV4LWRpcmVjdGlvbjpjb2x1bW47Z2FwOjEycHg7YWxpZ24taXRlbXM6c3RyZXRjaDt9CiAgLmJ0bi1nb2xkLC5idG4tb3V0bGluZS1saWdodHt0ZXh0LWFsaWduOmNlbnRlcjt9CiAgLmZvb3Rlci10b3B7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOjFmcjtnYXA6MjRweDt9CiAgLmV4cC1jb250ZW50e3BhZGRpbmc6MCAyMHB4O30uZXhwLXRpdGxle2ZvbnQtc2l6ZTozMnB4O30KfQoKLyog4pSA4pSAIFJFU1BPTlNJVkUgQURESVRJT05TIOKUgOKUgCAqLwpAbWVkaWEobWF4LXdpZHRoOjEwMjRweCl7LnNlY3Rpb24tdGl0bGV7Zm9udC1zaXplOjM2cHg7bGV0dGVyLXNwYWNpbmc6MnB4O30uc2VjdGlvbi1oZWFke21hcmdpbi1ib3R0b206NDhweDt9LnJvb21zLXdyYXB7cGFkZGluZzo2MHB4IDAgMDt9Zm9vdGVye3BhZGRpbmc6NDBweCA0MHB4IDI0cHg7fS5mb290ZXItdG9we2dhcDo0MHB4O30uZXhwZXJpZW5jZXtoZWlnaHQ6NDIwcHg7fS50ZXN0aS1jYXJke3BhZGRpbmc6MjhweCAyNHB4O30uYm9va2luZy10aXRsZXtmb250LXNpemU6NDRweDt9LmV4cC1jb250ZW50e3BhZGRpbmc6MCA2MHB4O30uZXhwLXRpdGxle2ZvbnQtc2l6ZTo0MnB4O30uc2VjdGlvbi1leWVicm93e2ZvbnQtc2l6ZTo5cHg7bGV0dGVyLXNwYWNpbmc6NXB4O319CkBtZWRpYShtYXgtd2lkdGg6NzY3cHgpey5zZWN0aW9uLXRpdGxle2ZvbnQtc2l6ZToyNnB4O2xldHRlci1zcGFjaW5nOjFweDt9LnNlY3Rpb24taGVhZHttYXJnaW4tYm90dG9tOjI4cHg7fS5yb29tcy13cmFwe3BhZGRpbmc6NDBweCAwIDA7fS5zY3JvbGwtaW5kaWNhdG9ye2Rpc3BsYXk6bm9uZTt9Lmhlcm8tY3Rhe3BhZGRpbmc6MTRweCAyOHB4O30udGVzdGktY2FyZHtwYWRkaW5nOjI0cHggMjBweDt9Zm9vdGVye3BhZGRpbmc6NDBweCAxNnB4IDI0cHg7fX0KPC9zdHlsZT4KPC9oZWFkPgo8Ym9keT4KCjwhLS0gQ1VTVE9NIENVUlNPUiAtLT4KPGRpdiBpZD0iY3Vyc29yIj48L2Rpdj4KPGRpdiBpZD0iY3Vyc29yLXJpbmciPjwvZGl2PgoKPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZAgTkFWIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAtLT4KPG5hdiBpZD0ibWFpbk5hdiI+CiAgPGRpdiBjbGFzcz0ibmF2LWxvZ28iPgogICAgPGltZyBzcmM9Imh0dHBzOi8vd3d3Lm1vc2FpY2hvc3RlbHMuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDI1LzA4L0xvZ28tVHJhbnNwZXJlbnQud2VicCIgYWx0PSJNb3NhaWMgSG9zdGVsIj4KICA8L2Rpdj4KICA8ZGl2IGNsYXNzPSJuYXYtbGlua3MiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vIj5Ib21lPC9hPgogICAgPGEgaHJlZj0iIyI+U3RheTwvYT4KICAgIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lm1vc2FpY2hvc3RlbHMuY29tL2dhbGxlcnkvIj5HYWxsZXJ5PC9hPgogICAgPGEgaHJlZj0iIyI+RXhwZXJpZW5jZXM8L2E+CiAgICA8YSBocmVmPSJodHRwczovL3d3dy5tb3NhaWNob3N0ZWxzLmNvbS9hYm91dC8iPkFib3V0PC9hPgogICAgPGEgaHJlZj0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vY29udGFjdC8iPkNvbnRhY3Q8L2E+CiAgPC9kaXY+CiAgPGJ1dHRvbiBjbGFzcz0ibmF2LWhhbWJ1cmdlciIgaWQ9Im5hdkhhbSIgYXJpYS1sYWJlbD0iT3BlbiBtZW51Ij48c3Bhbj48L3NwYW4+PHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj48L2J1dHRvbj4KICA8YSBocmVmPSJodHRwczovL3d3dy5tb3NhaWNob3N0ZWxzLmNvbS9ib29rLW5vdy8iIGNsYXNzPSJuYXYtYm9vayI+Qm9vayBOb3c8L2E+CjwvbmF2PgoKPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZAgSEVSTyDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+CjxzZWN0aW9uIGNsYXNzPSJoZXJvIj4KICA8IS0tIFRpbGUgY29sb3VyIHN0cmlwZSDigJQgbG9nbyBhcmNoIHJlZmVyZW5jZSAtLT4KICA8ZGl2IGNsYXNzPSJoZXJvLXRvcC1zdHJpcGUiIGlkPSJoZXJvU3RyaXBlIj48L2Rpdj4KCiAgPCEtLSBSZWFsIGhvc3RlbCB2aWRlbyAtLT4KICA8dmlkZW8gY2xhc3M9Imhlcm8tdmlkZW8iIGF1dG9wbGF5IG11dGVkIGxvb3AgcGxheXNpbmxpbmU+CiAgICA8c291cmNlIHNyYz0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMjUvMTAvSG9tZS1QYWdlLVZpZGVvLm1wNCIgdHlwZT0idmlkZW8vbXA0Ij4KICA8L3ZpZGVvPgogIDxkaXYgY2xhc3M9Imhlcm8tb3ZlcmxheSI+PC9kaXY+CgogIDxkaXYgY2xhc3M9Imhlcm8tY29udGVudCI+CiAgICA8ZGl2IGNsYXNzPSJoZXJvLWV5ZWJyb3ciPgogICAgICA8ZGl2IGNsYXNzPSJ0aWxlLWljb24iIGlkPSJoZXJvVGlsZUwiPjwvZGl2PgogICAgICBXaGVyZSBDdWx0dXJlIE1lZXRzIENvbWZvcnQKICAgICAgPGRpdiBjbGFzcz0idGlsZS1pY29uIiBpZD0iaGVyb1RpbGVSIj48L2Rpdj4KICAgIDwvZGl2PgoKICAgIDxwIGNsYXNzPSJoZXJvLXRhZ2xpbmUiPkVhY2ggZ3Vlc3QgYSBwaWVjZS4gRWFjaCBzdG9yeSBhIHRpbGUuPGJyPlRvZ2V0aGVyLCB3ZSBtYWtlIHNvbWV0aGluZyBiZWF1dGlmdWwuPC9wPgogICAgPGRpdiBjbGFzcz0iaGVyby1kaXZpZGVyIiBpZD0iaGVyb0RpdmlkZXIiPjwvZGl2PgogIDwvZGl2PgoKICA8ZGl2IGNsYXNzPSJzY3JvbGwtaW5kaWNhdG9yIj4KICAgIDxkaXYgY2xhc3M9InNjcm9sbC10ZXh0Ij5TY3JvbGw8L2Rpdj4KICAgIDxkaXYgY2xhc3M9InNjcm9sbC1saW5lIj48L2Rpdj4KICA8L2Rpdj4KPC9zZWN0aW9uPgoKPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZAgU1RBVFMgQkFORCDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+CjxkaXYgY2xhc3M9InN0YXRzLWJhbmQiPgogIDxkaXYgY2xhc3M9InN0YXQgcmV2ZWFsIj48ZGl2IGNsYXNzPSJzdGF0LW51bSI+NTAwKzwvZGl2PjxkaXYgY2xhc3M9InN0YXQtbGFiZWwiPkhhcHB5IEd1ZXN0czwvZGl2PjwvZGl2PgogIDxkaXYgY2xhc3M9InN0YXQgcmV2ZWFsIHJldmVhbC1kZWxheS0xIj48ZGl2IGNsYXNzPSJzdGF0LW51bSI+NC45IOKYhTwvZGl2PjxkaXYgY2xhc3M9InN0YXQtbGFiZWwiPkF2ZXJhZ2UgUmF0aW5nPC9kaXY+PC9kaXY+CiAgPGRpdiBjbGFzcz0ic3RhdCByZXZlYWwgcmV2ZWFsLWRlbGF5LTIiPjxkaXYgY2xhc3M9InN0YXQtbnVtIj41PC9kaXY+PGRpdiBjbGFzcz0ic3RhdC1sYWJlbCI+Um9vbSBUeXBlczwvZGl2PjwvZGl2PgogIDxkaXYgY2xhc3M9InN0YXQgcmV2ZWFsIHJldmVhbC1kZWxheS0zIj48ZGl2IGNsYXNzPSJzdGF0LW51bSI+MjAyNTwvZGl2PjxkaXYgY2xhc3M9InN0YXQtbGFiZWwiPkVzdC4gVmFyYW5hc2k8L2Rpdj48L2Rpdj4KPC9kaXY+Cgo8IS0tIFRJTEUgRElWSURFUiAtLT4KPGRpdiBjbGFzcz0idGlsZS1hY2NlbnQiIGlkPSJkaXYxIj48L2Rpdj4KCjwhLS0g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIFJPT01TIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAtLT4KPGRpdiBjbGFzcz0icm9vbXMtd3JhcCByZXZlYWwiPgogIDxkaXYgY2xhc3M9InNlY3Rpb24iPgogICAgPGRpdiBjbGFzcz0ic2VjdGlvbi1oZWFkIj4KICAgICAgPGRpdiBjbGFzcz0ic2VjdGlvbi1leWVicm93Ij5PdXIgU3BhY2VzPC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9InNlY3Rpb24tdGl0bGUiPkV2ZXJ5IFJvb20sPGJyPmEgPGVtPlVuaXF1ZSBUaWxlPC9lbT48L2Rpdj4KICAgICAgPGRpdiBjbGFzcz0idGl0bGUtdGlsZS1saW5lIiBpZD0icm9vbXNUaWxlTGluZSI+PC9kaXY+CiAgICA8L2Rpdj4KICA8L2Rpdj4KICA8ZGl2IGNsYXNzPSJyb29tcy1ncmlkIj4KICAgIDwhLS0gQ2FyZCAxIOKAlCBsYXJnZTogUHJpdmF0ZSBSb29tIC0tPgogICAgPGRpdiBjbGFzcz0icm9vbS1jYXJkIGhlcm8tY2FyZCI+CiAgICAgIDxkaXYgY2xhc3M9InJvb20tdG9wLWFjY2VudCIgaWQ9InJhMSI+PC9kaXY+CiAgICAgIDxpbWcgY2xhc3M9InJvb20tcGhvdG8iIHNyYz0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMjYvMDIvSU1HXzE5MzEtMS1zY2FsZWQuanBnIiBhbHQ9IlByaXZhdGUgUm9vbSI+CiAgICAgIDxkaXYgY2xhc3M9InJvb20tb3ZlcmxheSI+CiAgICAgICAgPGRpdiBjbGFzcz0icm9vbS10YWciPlByaXZhdGU8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJyb29tLW5hbWUiPlByaXZhdGUgUm9vbTwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InJvb20tbWV0YSI+QUMgwrcgRW5zdWl0ZSDCtyBXaUZpIMK3IExvY2tlcnM8L2Rpdj4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KICAgIDwhLS0gQ2FyZCAyOiA4LUJlZCBNaXhlZCBEb3JtIC0tPgogICAgPGRpdiBjbGFzcz0icm9vbS1jYXJkIj4KICAgICAgPGRpdiBjbGFzcz0icm9vbS10b3AtYWNjZW50IiBpZD0icmEyIj48L2Rpdj4KICAgICAgPGltZyBjbGFzcz0icm9vbS1waG90byIgc3JjPSJodHRwczovL3d3dy5tb3NhaWNob3N0ZWxzLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAyNS8xMS9JTUdfMTkzMy0yLXNjYWxlZC5qcGciIGFsdD0iOC1CZWQgTWl4ZWQgRG9ybSI+CiAgICAgIDxkaXYgY2xhc3M9InJvb20tb3ZlcmxheSI+CiAgICAgICAgPGRpdiBjbGFzcz0icm9vbS10YWciPk1peGVkIERvcm08L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJyb29tLW5hbWUiPjgtQmVkIERvcm08L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJyb29tLW1ldGEiPkFDIMK3IExvY2tlcnMgwrcgV2lGaSDCtyBTaGFyZWQgQmF0aDwvZGl2PgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogICAgPCEtLSBDYXJkIDM6IDYtQmVkIE1peGVkIERvcm0gLS0+CiAgICA8ZGl2IGNsYXNzPSJyb29tLWNhcmQiPgogICAgICA8ZGl2IGNsYXNzPSJyb29tLXRvcC1hY2NlbnQiIGlkPSJyYTMiPjwvZGl2PgogICAgICA8aW1nIGNsYXNzPSJyb29tLXBob3RvIiBzcmM9Imh0dHBzOi8vd3d3Lm1vc2FpY2hvc3RlbHMuY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDI1LzExL0lNR18yNzIzLTItc2NhbGVkLmpwZyIgYWx0PSI2LUJlZCBNaXhlZCBEb3JtIj4KICAgICAgPGRpdiBjbGFzcz0icm9vbS1vdmVybGF5Ij4KICAgICAgICA8ZGl2IGNsYXNzPSJyb29tLXRhZyI+TWl4ZWQgRG9ybTwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InJvb20tbmFtZSI+Ni1CZWQgRG9ybTwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InJvb20tbWV0YSI+QUMgwrcgTG9ja2VycyDCtyBXaUZpIMK3IFNoYXJlZCBCYXRoPC9kaXY+CiAgICAgIDwvZGl2PgogICAgPC9kaXY+CiAgICA8IS0tIENhcmQgNDogNC1CZWQgTWl4ZWQgRG9ybSAtLT4KICAgIDxkaXYgY2xhc3M9InJvb20tY2FyZCI+CiAgICAgIDxkaXYgY2xhc3M9InJvb20tdG9wLWFjY2VudCIgaWQ9InJhNCI+PC9kaXY+CiAgICAgIDxpbWcgY2xhc3M9InJvb20tcGhvdG8iIHNyYz0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMjUvMTEvSU1HXzI3MzMtMy1zY2FsZWQuanBnIiBhbHQ9IjQtQmVkIE1peGVkIERvcm0iPgogICAgICA8ZGl2IGNsYXNzPSJyb29tLW92ZXJsYXkiPgogICAgICAgIDxkaXYgY2xhc3M9InJvb20tdGFnIj5NaXhlZCBEb3JtPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0icm9vbS1uYW1lIj40LUJlZCBEb3JtPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0icm9vbS1tZXRhIj5BQyDCtyBMb2NrZXJzIMK3IFdpRmkgwrcgU2hhcmVkIEJhdGg8L2Rpdj4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KICAgIDwhLS0gQ2FyZCA1OiA2LUJlZCBGZW1hbGUgRG9ybSAtLT4KICAgIDxkaXYgY2xhc3M9InJvb20tY2FyZCI+CiAgICAgIDxkaXYgY2xhc3M9InJvb20tdG9wLWFjY2VudCIgaWQ9InJhNSI+PC9kaXY+CiAgICAgIDxpbWcgY2xhc3M9InJvb20tcGhvdG8iIHNyYz0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMjYvMDIvSU1HXzE5MjAtc2NhbGVkLmpwZyIgYWx0PSI2LUJlZCBGZW1hbGUgRG9ybSI+CiAgICAgIDxkaXYgY2xhc3M9InJvb20tb3ZlcmxheSI+CiAgICAgICAgPGRpdiBjbGFzcz0icm9vbS10YWciPkxhZGllcyBPbmx5PC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0icm9vbS1uYW1lIj42LUJlZCBGZW1hbGUgRG9ybTwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InJvb20tbWV0YSI+QUMgwrcgTG9ja2VycyDCtyBXaUZpIMK3IFNlY3VyZTwvZGl2PgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KCjwhLS0gVElMRSBESVZJREVSIC0tPgo8ZGl2IGNsYXNzPSJ0aWxlLWFjY2VudCIgaWQ9ImRpdjIiPjwvZGl2PgoKPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZAgUEhJTE9TT1BIWSDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+CjxkaXYgY2xhc3M9InBoaWxvc29waHkgcmV2ZWFsIj4KICA8ZGl2IGNsYXNzPSJwaGlsb3NvcGh5LWlubmVyIj4KICAgIDxkaXYgY2xhc3M9InBoaWwtY29sIj4KICAgICAgPGRpdiBjbGFzcz0icGhpbC10aWxlLWljb24iIGlkPSJwdDEiPjwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJwaGlsLXRpdGxlIj5IZWFydCBvZiBWYXJhbmFzaTwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJwaGlsLWJvZHkiPlNpdHVhdGVkIHN0ZXBzIGZyb20gdGhlIEdoYXRzLCB3ZSBwdXQgeW91IGF0IHRoZSBjZW50cmUgb2Ygb25lIG9mIHRoZSB3b3JsZCdzIG1vc3QgYW5jaWVudCBhbmQgc3Bpcml0dWFsIGNpdGllcy48L2Rpdj4KICAgIDwvZGl2PgogICAgPGRpdiBjbGFzcz0icGhpbC1jb2wiPgogICAgICA8ZGl2IGNsYXNzPSJwaGlsLXRpbGUtaWNvbiIgaWQ9InB0MiI+PC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9InBoaWwtdGl0bGUiPkNvbW11bml0eSBGaXJzdDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJwaGlsLWJvZHkiPlRyYXZlbGxlcnMgZnJvbSBldmVyeSBjb3JuZXIgb2YgdGhlIHdvcmxkIG1lZXQgaGVyZSDigJQgc2hhcmluZyBzdG9yaWVzLCBtYWtpbmcgZnJpZW5kcywgYW5kIGV4cGxvcmluZyB0b2dldGhlci48L2Rpdj4KICAgIDwvZGl2PgogICAgPGRpdiBjbGFzcz0icGhpbC1jb2wiPgogICAgICA8ZGl2IGNsYXNzPSJwaGlsLXRpbGUtaWNvbiIgaWQ9InB0MyI+PC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9InBoaWwtdGl0bGUiPlNhZmUgJiBDb21mb3J0YWJsZTwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJwaGlsLWJvZHkiPkNsZWFuIHJvb21zLCByZWxpYWJsZSBXaUZpLCBob3Qgc2hvd2VycywgMjRoIHNlY3VyaXR5LiBFdmVyeXRoaW5nIHlvdSBuZWVkIHRvIHJlc3Qgd2VsbCBiZWZvcmUgeW91ciBuZXh0IGFkdmVudHVyZS48L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KCjwhLS0g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIEVYUEVSSUVOQ0UgKGZ1bGwgYmxlZWQpIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAtLT4KPGRpdiBjbGFzcz0iZXhwZXJpZW5jZSByZXZlYWwiPgogIDxpbWcgY2xhc3M9ImV4cC1waG90byIgaWQ9ImV4cFBob3RvIgogICAgc3JjPSJodHRwczovL3d3dy5tb3NhaWNob3N0ZWxzLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAyNi8wMi9JTUdfMTM1Ny1zY2FsZWQuanBnIiBhbHQ9IkV4cGVyaWVuY2UiPgogIDxkaXYgY2xhc3M9ImV4cC1vdmVybGF5Ij48L2Rpdj4KICA8ZGl2IGNsYXNzPSJleHAtY29udGVudCI+CiAgICA8ZGl2IGNsYXNzPSJleHAtZXllYnJvdyI+VGhlIFZhcmFuYXNpIEV4cGVyaWVuY2U8L2Rpdj4KICAgIDxoMiBjbGFzcz0iZXhwLXRpdGxlIj5Nb3JlIFRoYW48YnI+YSA8ZW0+UGxhY2UgdG8gU2xlZXA8L2VtPjwvaDI+CiAgICA8cCBjbGFzcz0iZXhwLWJvZHkiPldha2UgdXAgc3RlcHMgZnJvbSB0aGUgR2hhdHMuIFdhdGNoIHRoZSBHYW5nYSBBYXJ0aSBmcm9tIG91ciByb29mdG9wLiBKb2luIHdhbGtpbmcgdG91cnMsIGNvb2tpbmcgY2xhc3NlcywgYW5kIHN1bnJpc2UgYm9hdCByaWRlcyDigJQgYWxsIGN1cmF0ZWQgYnkgbG9jYWxzIHdobyBsb3ZlIHRoaXMgY2l0eS48L3A+CiAgICA8ZGl2IGNsYXNzPSJleHAtdGlsZS1zdHJpcCIgaWQ9ImV4cFN0cmlwIj48L2Rpdj4KICAgIDxhIGNsYXNzPSJidG4tbGlnaHQiIGhyZWY9Ii9nYWxsZXJ5Ij5FeHBsb3JlIEdhbGxlcnk8L2E+CiAgPC9kaXY+CjwvZGl2PgoKPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZAgVEVTVElNT05JQUxTIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAtLT4KPGRpdiBjbGFzcz0idGVzdGktd3JhcCByZXZlYWwiPgogIDxkaXYgY2xhc3M9InNlY3Rpb24taGVhZCI+CiAgICA8ZGl2IGNsYXNzPSJzZWN0aW9uLWV5ZWJyb3ciPkd1ZXN0IFN0b3JpZXM8L2Rpdj4KICAgIDxkaXYgY2xhc3M9InNlY3Rpb24tdGl0bGUiPkVhY2ggR3Vlc3QsIGE8YnI+PGVtPlBpZWNlIG9mIE91ciBNb3NhaWM8L2VtPjwvZGl2PgogICAgPGRpdiBjbGFzcz0idGl0bGUtdGlsZS1saW5lIiBpZD0idGVzdGlUaWxlTGluZSI+PC9kaXY+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0idGVzdGktZ3JpZCI+CiAgICA8ZGl2IGNsYXNzPSJ0ZXN0aS1jYXJkIHJldmVhbCI+CiAgICAgIDxkaXYgY2xhc3M9InRlc3RpLWFjY2VudCIgaWQ9InRhMSI+PC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9InRlc3RpLXF1b3RlIj4iVGhlIHZpYmUgaGVyZSBpcyB1bmxpa2UgYW55IG90aGVyIGhvc3RlbCBpbiBJbmRpYS4gR3JlYXQgbG9jYXRpb24sIHdhcm0gc3RhZmYsIGFuZCB0aGUga2luZCBvZiBwZW9wbGUgeW91IGFjdHVhbGx5IHdhbnQgdG8gdHJhdmVsIHdpdGguIjwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJ0ZXN0aS1uYW1lIj7igJQgUHJpeWEgUy4sIE11bWJhaTwvZGl2PgogICAgPC9kaXY+CiAgICA8ZGl2IGNsYXNzPSJ0ZXN0aS1jYXJkIHJldmVhbCByZXZlYWwtZGVsYXktMSI+CiAgICAgIDxkaXYgY2xhc3M9InRlc3RpLWFjY2VudCIgaWQ9InRhMiI+PC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9InRlc3RpLXF1b3RlIj4iQmVzdCBob3N0ZWwgc3RheSBJJ3ZlIGhhZCBpbiBJbmRpYS4gQ2xlYW4sIHNvY2lhbCwgcGVyZmVjdGx5IGxvY2F0ZWQg4oCUIHRoZSByb29mdG9wIHZpZXcgb2YgVmFyYW5hc2kgYXQgc3Vuc2V0IGlzIHNvbWV0aGluZyBlbHNlLiI8L2Rpdj4KICAgICAgPGRpdiBjbGFzcz0idGVzdGktbmFtZSI+4oCUIEphbWVzIEwuLCBMb25kb248L2Rpdj4KICAgIDwvZGl2PgogICAgPGRpdiBjbGFzcz0idGVzdGktY2FyZCByZXZlYWwgcmV2ZWFsLWRlbGF5LTIiPgogICAgICA8ZGl2IGNsYXNzPSJ0ZXN0aS1hY2NlbnQiIGlkPSJ0YTMiPjwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJ0ZXN0aS1xdW90ZSI+Ildhcm0sIHdlbGNvbWluZyBhbmQgZnVsbCBvZiBlbmVyZ3kuIE1ldCBzb21lIG9mIG15IGZhdm91cml0ZSB0cmF2ZWwgZnJpZW5kcyBoZXJlLiBBbHJlYWR5IHBsYW5uaW5nIHRvIGNvbWUgYmFjay4iPC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9InRlc3RpLW5hbWUiPuKAlCBBaWtvIFQuLCBUb2t5bzwvZGl2PgogICAgPC9kaXY+CiAgPC9kaXY+CjwvZGl2PgoKPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZAgQk9PS0lORyBDVEEg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIC0tPgo8ZGl2IGNsYXNzPSJib29raW5nIj4KICA8ZGl2IGNsYXNzPSJib29raW5nLXN0cmlwZSIgaWQ9ImJvb2tTdHJpcGUiPjwvZGl2PgogIDxkaXYgY2xhc3M9ImJvb2tpbmctY29udGVudCByZXZlYWwiPgogICAgPGRpdiBjbGFzcz0iYm9va2luZy1leWVicm93Ij5SZWFkeSB0byBTdGF5PzwvZGl2PgogICAgPGRpdiBjbGFzcz0iYm9va2luZy10aXRsZSI+QmVnaW4gWW91ciA8c3Bhbj5Nb3NhaWM8L3NwYW4+IFN0b3J5PC9kaXY+CiAgICA8ZGl2IGNsYXNzPSJib29raW5nLXN1YiI+VmFyYW5hc2kgwrcgSW5kaWEgwrcgRXN0LiAyMDI1PC9kaXY+CiAgICA8ZGl2IGNsYXNzPSJib29raW5nLWJ0bnMiPgogICAgICA8YSBjbGFzcz0iYnRuLWdvbGQiIGhyZWY9IiMiPkJvb2sgWW91ciBTdGF5PC9hPgogICAgICA8YSBjbGFzcz0iYnRuLW91dGxpbmUtbGlnaHQiIGhyZWY9IiMiPkdldCBpbiBUb3VjaDwvYT4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KCjwhLS0g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIEZPT1RFUiDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+Cjxmb290ZXI+CiAgPGRpdiBjbGFzcz0iZm9vdGVyLXRvcCI+CiAgICA8aW1nIGxvYWRpbmc9ImxhenkiIHNyYz0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMjUvMDgvTG9nby1UcmFuc3BlcmVudC53ZWJwIiBhbHQ9Ik1vc2FpYyBIb3N0ZWwiIHN0eWxlPSJoZWlnaHQ6MTEwcHg7d2lkdGg6YXV0bztmaWx0ZXI6YnJpZ2h0bmVzcygwKSBpbnZlcnQoMSk7b3BhY2l0eTowLjk7Ij4KICAgIDxkaXYgY2xhc3M9ImZvb3Rlci1saW5rcy13cmFwIj4KICAgICAgPGRpdiBjbGFzcz0iZm9vdGVyLWxpbmtzIj4KICAgICAgICA8ZGl2IGNsYXNzPSJmb290ZXItaGVhZGluZyI+RXhwbG9yZTwvZGl2PgogICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lm1vc2FpY2hvc3RlbHMuY29tL2dhbGxlcnkvIj5HYWxsZXJ5PC9hPgogICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lm1vc2FpY2hvc3RlbHMuY29tL2Fib3V0LyI+QWJvdXQgVXM8L2E+CiAgICAgICAgPGEgaHJlZj0iIyI+RXhwZXJpZW5jZXM8L2E+CiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly93d3cubW9zYWljaG9zdGVscy5jb20vY29udGFjdC8iPkNvbnRhY3Q8L2E+CiAgICAgIDwvZGl2PgogICAgICA8ZGl2IGNsYXNzPSJmb290ZXItbGlua3MiPgogICAgICAgIDxkaXYgY2xhc3M9ImZvb3Rlci1oZWFkaW5nIj5Db25uZWN0PC9kaXY+CiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly93YS5tZS85MTkxMjU0OTIyMjUiIHRhcmdldD0iX2JsYW5rIj5XaGF0c0FwcDwvYT4KICAgICAgICA8YSBocmVmPSJtYWlsdG86bW9zYWljaG9zdGVsc0BnbWFpbC5jb20iPkVtYWlsIFVzPC9hPgogICAgICAgIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lmluc3RhZ3JhbS5jb20vbW9zYWljaG9zdGVscyIgdGFyZ2V0PSJfYmxhbmsiPkluc3RhZ3JhbTwvYT4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KICA8L2Rpdj4KICA8ZGl2IGNsYXNzPSJmb290ZXItYm90dG9tIj4KICAgIDxkaXYgY2xhc3M9ImZvb3Rlci1jb3B5Ij7CqSAyMDI1IE1vc2FpYyBIb3N0ZWwgVmFyYW5hc2kuIEFsbCByaWdodHMgcmVzZXJ2ZWQuPC9kaXY+CiAgICA8ZGl2IGNsYXNzPSJmb290ZXItdGlsZS1zdHJpcCIgaWQ9ImZvb3RlclN0cmlwIj48L2Rpdj4KICAgIDxkaXYgY2xhc3M9ImZvb3Rlci1jb3B5Ij5NYWRlIHdpdGgg4pmlIGluIFZhcmFuYXNpPC9kaXY+CiAgPC9kaXY+CjwvZm9vdGVyPgoKPHNjcmlwdD4KLy8g4pSA4pSAIENPTE9VUiBQQUxFVFRFIChsb2dvKSDilIDilIAKY29uc3QgUEFMID0gewogIGdvbGQ6ICAgWycjQzg4NjBBJywnI0U4Qjg0QicsJyNENDkzMEYnLCcjRjBDMDYwJ10sCiAgdGVhbDogICBbJyMxQTZCN0EnLCcjMkQ5QUFBJywnIzBENEE1NSddLAogIGJ1cmc6ICAgWycjOEIxQTFBJywnI0EwMjAyMCcsJyM2QjEwMTAnXSwKICBjb2JhbHQ6IFsnIzFBM0E2QicsJyMyQTVBOUInLCcjMEQxQTQwJ10sCiAgYnJvd246ICBbJyM1QzNBMUUnLCcjN0E0RjJBJywnIzNBMjAxMCddLAogIHNhZ2U6ICAgWycjM0Q2QjNBJywnIzJENUEyQSddLAp9Owpjb25zdCBMT0dPX0NPTE9SUyA9IFsnI0M4ODYwQScsJyM4QjFBMUEnLCcjMUE2QjdBJywnIzFBM0E2QicsJyM1QzNBMUUnLCcjRThCODRCJywnIzNENkIzQScsJyNBMDIwMjAnLCcjMkQ5QUFBJywnIzdBNEYyQSddOwpmdW5jdGlvbiBwaWNrKGFycil7cmV0dXJuIGFycltNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqYXJyLmxlbmd0aCldO30KCi8vIEZpbGwgYSBzdHJpcCB3aXRoIGxvZ28gY29sb3VycwpmdW5jdGlvbiBmaWxsU3RyaXAoaWQsIGNvbG9ycyl7CiAgY29uc3QgZWw9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpOwogIGlmKCFlbCkgcmV0dXJuOwogIGNvbG9ycy5mb3JFYWNoKGM9PnsgY29uc3Qgcz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7IHMuc3R5bGUuZmxleD0nMSc7IHMuc3R5bGUuYmFja2dyb3VuZD1jOyBlbC5hcHBlbmRDaGlsZChzKTsgfSk7Cn0KLy8gRmlsbCBhIHNtYWxsIGljb24gZ3JpZApmdW5jdGlvbiBmaWxsSWNvbihpZCwgcGFsZXR0ZSl7CiAgY29uc3QgZWw9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpOwogIGlmKCFlbCkgcmV0dXJuOwogIGNvbnN0IG49ZWwuc3R5bGUuZ3JpZFRlbXBsYXRlQ29sdW1ucz9lbC5zdHlsZS5ncmlkVGVtcGxhdGVDb2x1bW5zLm1hdGNoKC9cZCtweC9nKS5sZW5ndGg6MzsKICBjb25zdCByb3dzPWVsLnN0eWxlLmdyaWRUZW1wbGF0ZVJvd3M/ZWwuc3R5bGUuZ3JpZFRlbXBsYXRlUm93cy5tYXRjaCgvXGQrcHgvZykubGVuZ3RoOjM7CiAgY29uc3QgY291bnQ9KG58fDMpKihyb3dzfHwzKTsKICBmb3IobGV0IGk9MDtpPGNvdW50O2krKyl7CiAgICBjb25zdCBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTsgcy5zdHlsZS5iYWNrZ3JvdW5kPXBpY2socGFsZXR0ZSk7IHMuc3R5bGUuYm9yZGVyUmFkaXVzPScycHgnOyBzLnN0eWxlLmRpc3BsYXk9J2Jsb2NrJzsgZWwuYXBwZW5kQ2hpbGQocyk7CiAgfQp9CgovLyBIZXJvIHN0cmlwZQpmaWxsU3RyaXAoJ2hlcm9TdHJpcGUnLCBMT0dPX0NPTE9SUyk7CgovLyBIZXJvIHRpbGUgaWNvbnMKWydoZXJvVGlsZUwnLCdoZXJvVGlsZVInXS5mb3JFYWNoKGlkPT57CiAgY29uc3QgZWw9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpOwogIGlmKCFlbCkgcmV0dXJuOwogIExPR09fQ09MT1JTLnNsaWNlKDAsOSkuZm9yRWFjaChjPT57IGNvbnN0IHM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOyBzLnN0eWxlLmJhY2tncm91bmQ9Yzsgcy5zdHlsZS5ib3JkZXJSYWRpdXM9JzFweCc7IGVsLmFwcGVuZENoaWxkKHMpOyB9KTsKfSk7CgovLyBIZXJvIGRpdmlkZXIKZmlsbFN0cmlwKCdoZXJvRGl2aWRlcicsIFsnI0M4ODYwQScsJyM4QjFBMUEnLCcjMUE2QjdBJywnIzFBM0E2QicsJyM1QzNBMUUnXSk7CgovLyBEaXZpZGVycwpbJ2RpdjEnLCdkaXYyJywnZGl2MycsJ2RpdjQnXS5mb3JFYWNoKGlkPT5maWxsU3RyaXAoaWQsIExPR09fQ09MT1JTKSk7CgovLyBUaXRsZSB0aWxlIGxpbmVzClsncm9vbXNUaWxlTGluZScsJ2dhbFRpbGVMaW5lJywndGVzdGlUaWxlTGluZSddLmZvckVhY2goaWQ9PmZpbGxTdHJpcChpZCwgWycjQzg4NjBBJywnIzhCMUExQScsJyMxQTZCN0EnLCcjMUEzQTZCJywnIzVDM0ExRSddKSk7CgovLyBSb29tIGFjY2VudCBiYXJzCmNvbnN0IHJvb21QYWxzPVsKICBbLi4uUEFMLmdvbGQsLi4uUEFMLnRlYWxdLAogIFsuLi5QQUwudGVhbCwuLi5QQUwuY29iYWx0XSwKICBbLi4uUEFMLmJ1cmcsLi4uUEFMLmdvbGRdLAogIFsuLi5QQUwuY29iYWx0LC4uLlBBTC5zYWdlXSwKICBbLi4uUEFMLnNhZ2UsLi4uUEFMLmdvbGRdLApdOwpbMSwyLDMsNCw1XS5mb3JFYWNoKGk9PnsKICBjb25zdCBlbD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmEnK2kpOwogIGlmKCFlbCkgcmV0dXJuOwogIGNvbnN0IHBhbD1yb29tUGFsc1soaS0xKSVyb29tUGFscy5sZW5ndGhdOwogIGZvcihsZXQgaz0wO2s8MjA7aysrKXtjb25zdCBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtzLnN0eWxlLmZsZXg9JzEnO3Muc3R5bGUuYmFja2dyb3VuZD1waWNrKHBhbCk7ZWwuYXBwZW5kQ2hpbGQocyk7fQp9KTsKCi8vIFBoaWxvc29waHkgaWNvbnMgKDTDlzQpCltbJ3B0MScsUEFMLmdvbGQsLi4uUEFMLnRlYWxdLFsncHQyJywuLi5QQUwuYnVyZywuLi5QQUwuY29iYWx0XSxbJ3B0MycsLi4uUEFMLnNhZ2UsLi4uUEFMLmdvbGRdXS5mb3JFYWNoKChbaWQsLi4ucGFsXSk9PnsKICBjb25zdCBlbD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7CiAgaWYoIWVsKSByZXR1cm47CiAgZm9yKGxldCBpPTA7aTwxNjtpKyspe2NvbnN0IHM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO3Muc3R5bGUuYmFja2dyb3VuZD1waWNrKHBhbCk7cy5zdHlsZS5ib3JkZXJSYWRpdXM9JzJweCc7cy5zdHlsZS5kaXNwbGF5PSdibG9jayc7ZWwuYXBwZW5kQ2hpbGQocyk7fQp9KTsKCi8vIEV4cGVyaWVuY2Ugc3RyaXAKZmlsbFN0cmlwKCdleHBTdHJpcCcsIExPR09fQ09MT1JTKTsKCi8vIEdhbGxlcnkgbGVmdCBib3JkZXIgYWxyZWFkeSBDU1MKCi8vIFRlc3RpbW9uaWFsIGFjY2VudCBiYXJzCltbJ3RhMScsUEFMLmdvbGQsUEFMLnRlYWxdLFsndGEyJyxQQUwuYnVyZyxQQUwuY29iYWx0XSxbJ3RhMycsUEFMLnNhZ2UsUEFMLmdvbGRdXS5mb3JFYWNoKChbaWQscDEscDJdKT0+ewogIGNvbnN0IGVsPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKTsKICBpZighZWwpIHJldHVybjsKICBmb3IobGV0IGs9MDtrPDIwO2srKyl7Y29uc3Qgcz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7cy5zdHlsZS5mbGV4PScxJztzLnN0eWxlLmJhY2tncm91bmQ9cGljayhbLi4ucDEsLi4ucDJdKTtlbC5hcHBlbmRDaGlsZChzKTt9Cn0pOwoKLy8gQm9va2luZyBzdHJpcGUg4oCUIGZ1bGwgcmFpbmJvdwpmaWxsU3RyaXAoJ2Jvb2tTdHJpcGUnLCBbLi4uTE9HT19DT0xPUlMsLi4uTE9HT19DT0xPUlNdKTsKCi8vIEZvb3RlciBzdHJpcApmaWxsU3RyaXAoJ2Zvb3RlclN0cmlwJywgWycjQzg4NjBBJywnIzhCMUExQScsJyMxQTZCN0EnLCcjMUEzQTZCJywnIzNENkIzQSddKTsKCi8vIOKUgOKUgCBDVVNUT00gQ1VSU09SIOKUgOKUgApjb25zdCBjdXI9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2N1cnNvcicpOwpjb25zdCByaW5nPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjdXJzb3ItcmluZycpOwpkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLGU9PnsKICBjdXIuc3R5bGUubGVmdD1lLmNsaWVudFgrJ3B4JzsgY3VyLnN0eWxlLnRvcD1lLmNsaWVudFkrJ3B4JzsKICByaW5nLnN0eWxlLmxlZnQ9ZS5jbGllbnRYKydweCc7IHJpbmcuc3R5bGUudG9wPWUuY2xpZW50WSsncHgnOwp9KTsKZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnYSxidXR0b24sLnJvb20tY2FyZCwuZ2FsLWl0ZW0nKS5mb3JFYWNoKGVsPT57CiAgZWwuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsKCk9PnsKICAgIGN1ci5zdHlsZS53aWR0aD0nMjBweCc7IGN1ci5zdHlsZS5oZWlnaHQ9JzIwcHgnOwogICAgcmluZy5zdHlsZS53aWR0aD0nNTBweCc7IHJpbmcuc3R5bGUuaGVpZ2h0PSc1MHB4JzsKICB9KTsKICBlbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywoKT0+ewogICAgY3VyLnN0eWxlLndpZHRoPScxMHB4JzsgY3VyLnN0eWxlLmhlaWdodD0nMTBweCc7CiAgICByaW5nLnN0eWxlLndpZHRoPSczNnB4JzsgcmluZy5zdHlsZS5oZWlnaHQ9JzM2cHgnOwogIH0pOwp9KTsKCi8vIOKUgOKUgCBOQVYgU0NST0xMIOKUgOKUgApjb25zdCBuYXY9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21haW5OYXYnKTsKd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsKCk9PnsKICBuYXYuY2xhc3NMaXN0LnRvZ2dsZSgnc2Nyb2xsZWQnLCB3aW5kb3cuc2Nyb2xsWT44MCk7Cn0pOwoKLy8g4pSA4pSAIFNDUk9MTCBSRVZFQUwg4pSA4pSACmNvbnN0IG9ic2VydmVyPW5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcihlbnRyaWVzPT57CiAgZW50cmllcy5mb3JFYWNoKGU9PnsgaWYoZS5pc0ludGVyc2VjdGluZykgZS50YXJnZXQuY2xhc3NMaXN0LmFkZCgndmlzaWJsZScpOyB9KTsKfSx7dGhyZXNob2xkOjAuMTJ9KTsKZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnJldmVhbCcpLmZvckVhY2goZWw9Pm9ic2VydmVyLm9ic2VydmUoZWwpKTsKCi8vIOKUgOKUgCBQQVJBTExBWCBvbiBleHBlcmllbmNlIHBob3RvIOKUgOKUgApjb25zdCBleHBQaG90bz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXhwUGhvdG8nKTsKd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsKCk9PnsKICBpZighZXhwUGhvdG8pIHJldHVybjsKICBjb25zdCByZWN0PWV4cFBob3RvLmNsb3Nlc3QoJy5leHBlcmllbmNlJykuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgY29uc3QgcGN0PSh3aW5kb3cuaW5uZXJIZWlnaHQtcmVjdC50b3ApLyh3aW5kb3cuaW5uZXJIZWlnaHQrcmVjdC5oZWlnaHQpOwogIGV4cFBob3RvLnN0eWxlLnRyYW5zZm9ybT1gdHJhbnNsYXRlWSgkeyhwY3QtMC41KSo0MH1weClgOwp9LHtwYXNzaXZlOnRydWV9KTsKCi8vIOKUgOKUgCBTQ1JPTEwgUFJPR1JFU1MgQkFSIOKUgOKUgApjb25zdCBwcm9ncmVzc0Jhcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKcHJvZ3Jlc3NCYXIuc3R5bGUuY3NzVGV4dD0ncG9zaXRpb246Zml4ZWQ7dG9wOjA7bGVmdDowO2hlaWdodDozcHg7YmFja2dyb3VuZDpsaW5lYXItZ3JhZGllbnQoOTBkZWcsI0M4ODYwQSwjOEIxQTFBLCMxQTZCN0EpO3otaW5kZXg6OTk5OTt3aWR0aDowJTt0cmFuc2l0aW9uOndpZHRoIDAuMXM7cG9pbnRlci1ldmVudHM6bm9uZTsnOwpkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHByb2dyZXNzQmFyKTsKd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsKCk9PnsKICBjb25zdCBwY3Q9KHdpbmRvdy5zY3JvbGxZLyhkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodC13aW5kb3cuaW5uZXJIZWlnaHQpKSoxMDA7CiAgcHJvZ3Jlc3NCYXIuc3R5bGUud2lkdGg9cGN0KyclJzsKfSx7cGFzc2l2ZTp0cnVlfSk7CgovLyDilIDilIAgU1RBVCBDT1VOVEVSIEFOSU1BVElPTiDilIDilIAKY29uc3Qgc3RhdE51bXM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnN0YXQtbnVtJyk7CmNvbnN0IHN0YXRPYnNlcnZlcj1uZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoZW50cmllcz0+ewogIGVudHJpZXMuZm9yRWFjaChlbnRyeT0+ewogICAgaWYoIWVudHJ5LmlzSW50ZXJzZWN0aW5nKSByZXR1cm47CiAgICBjb25zdCBlbD1lbnRyeS50YXJnZXQ7CiAgICBjb25zdCB0ZXh0PWVsLnRleHRDb250ZW50OwogICAgY29uc3QgbnVtPXBhcnNlRmxvYXQodGV4dC5yZXBsYWNlKC9bXjAtOS5dL2csJycpKTsKICAgIGlmKCFudW18fHRleHQuaW5jbHVkZXMoJ+KYhScpfHx0ZXh0LmluY2x1ZGVzKCdFc3QnKSkgcmV0dXJuOwogICAgY29uc3Qgc3VmZml4PXRleHQucmVwbGFjZSgvW1xkLl0vZywnJyk7CiAgICBsZXQgc3RhcnQ9MDsgY29uc3QgZHVyPTE4MDA7CiAgICBjb25zdCBzdGVwPXRzPT57CiAgICAgIGlmKCFzdGFydCkgc3RhcnQ9dHM7CiAgICAgIGNvbnN0IHByb2c9TWF0aC5taW4oKHRzLXN0YXJ0KS9kdXIsMSk7CiAgICAgIGNvbnN0IGVhc2U9MS1NYXRoLnBvdygxLXByb2csMyk7CiAgICAgIGVsLnRleHRDb250ZW50PU1hdGgucm91bmQoZWFzZSpudW0pK3N1ZmZpeDsKICAgICAgaWYocHJvZzwxKSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoc3RlcCk7CiAgICB9OwogICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHN0ZXApOwogICAgc3RhdE9ic2VydmVyLnVub2JzZXJ2ZShlbCk7CiAgfSk7Cn0se3RocmVzaG9sZDowLjV9KTsKc3RhdE51bXMuZm9yRWFjaChlbD0+c3RhdE9ic2VydmVyLm9ic2VydmUoZWwpKTsKCi8vIOKUgOKUgCAzRCBUSUxUIG9uIHJvb20gY2FyZHMg4pSA4pSACmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5yb29tLWNhcmQnKS5mb3JFYWNoKGNhcmQ9PnsKICBjYXJkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsZT0+ewogICAgY29uc3QgcmVjdD1jYXJkLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgY29uc3QgeD0oKGUuY2xpZW50WC1yZWN0LmxlZnQpL3JlY3Qud2lkdGgtMC41KSoxMjsKICAgIGNvbnN0IHk9KChlLmNsaWVudFktcmVjdC50b3ApL3JlY3QuaGVpZ2h0LTAuNSkqLTEyOwogICAgY2FyZC5zdHlsZS50cmFuc2Zvcm09YHBlcnNwZWN0aXZlKDgwMHB4KSByb3RhdGVZKCR7eH1kZWcpIHJvdGF0ZVgoJHt5fWRlZykgc2NhbGUoMS4wMilgOwogICAgY2FyZC5zdHlsZS50cmFuc2l0aW9uPSd0cmFuc2Zvcm0gMC4xcyc7CiAgfSk7CiAgY2FyZC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywoKT0+ewogICAgY2FyZC5zdHlsZS50cmFuc2Zvcm09J3BlcnNwZWN0aXZlKDgwMHB4KSByb3RhdGVZKDApIHJvdGF0ZVgoMCkgc2NhbGUoMSknOwogICAgY2FyZC5zdHlsZS50cmFuc2l0aW9uPSd0cmFuc2Zvcm0gMC40cyBlYXNlJzsKICB9KTsKfSk7CgovLyDilIDilIAgTUFHTkVUSUMgQlVUVE9OUyDilIDilIAKZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmJ0bi1nb2xkLC5idG4tcHJpbWFyeSwuaGVyby1jdGEsLm5hdi1ib29rJykuZm9yRWFjaChidG49PnsKICBidG4uYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJyxlPT57CiAgICBjb25zdCByZWN0PWJ0bi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgIGNvbnN0IHg9KGUuY2xpZW50WC1yZWN0LmxlZnQtcmVjdC53aWR0aC8yKSowLjI1OwogICAgY29uc3QgeT0oZS5jbGllbnRZLXJlY3QudG9wLXJlY3QuaGVpZ2h0LzIpKjAuMjU7CiAgICBidG4uc3R5bGUudHJhbnNmb3JtPWB0cmFuc2xhdGUoJHt4fXB4LCR7eX1weClgOwogICAgYnRuLnN0eWxlLnRyYW5zaXRpb249J3RyYW5zZm9ybSAwLjFzJzsKICB9KTsKICBidG4uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsKCk9PnsKICAgIGJ0bi5zdHlsZS50cmFuc2Zvcm09J3RyYW5zbGF0ZSgwLDApJzsKICAgIGJ0bi5zdHlsZS50cmFuc2l0aW9uPSd0cmFuc2Zvcm0gMC40cyBlYXNlJzsKICB9KTsKfSk7CgovLyDilIDilIAgUklQUExFIG9uIGJ1dHRvbnMg4pSA4pSACmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5idG4tZ29sZCwuYnRuLXByaW1hcnksLmhlcm8tY3RhLC5uYXYtYm9vaycpLmZvckVhY2goYnRuPT57CiAgYnRuLnN0eWxlLm92ZXJmbG93PSdoaWRkZW4nO2J0bi5zdHlsZS5wb3NpdGlvbj0ncmVsYXRpdmUnOwogIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZT0+ewogICAgY29uc3Qgcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7CiAgICBjb25zdCByZWN0PWJ0bi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgIGNvbnN0IHNpemU9TWF0aC5tYXgocmVjdC53aWR0aCxyZWN0LmhlaWdodCkqMjsKICAgIHIuc3R5bGUuY3NzVGV4dD1gcG9zaXRpb246YWJzb2x1dGU7d2lkdGg6JHtzaXplfXB4O2hlaWdodDoke3NpemV9cHg7Ym9yZGVyLXJhZGl1czo1MCU7YmFja2dyb3VuZDpyZ2JhKDI1NSwyNTUsMjU1LDAuMjUpO3RyYW5zZm9ybTp0cmFuc2xhdGUoLTUwJSwtNTAlKSBzY2FsZSgwKTtsZWZ0OiR7ZS5jbGllbnRYLXJlY3QubGVmdH1weDt0b3A6JHtlLmNsaWVudFktcmVjdC50b3B9cHg7YW5pbWF0aW9uOnJpcHBsZSAwLjZzIGVhc2Utb3V0IGZvcndhcmRzO3BvaW50ZXItZXZlbnRzOm5vbmU7YDsKICAgIGJ0bi5hcHBlbmRDaGlsZChyKTsKICAgIHNldFRpbWVvdXQoKCk9PnIucmVtb3ZlKCksNzAwKTsKICB9KTsKfSk7CmNvbnN0IHJpcHBsZVN0eWxlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7CnJpcHBsZVN0eWxlLnRleHRDb250ZW50PSdAa2V5ZnJhbWVzIHJpcHBsZXt0b3t0cmFuc2Zvcm06dHJhbnNsYXRlKC01MCUsLTUwJSkgc2NhbGUoMSk7b3BhY2l0eTowO319JzsKZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChyaXBwbGVTdHlsZSk7CgovLyDilIDilIAgQUNUSVZFIE5BViBMSU5LIG9uIHNjcm9sbCDilIDilIAKY29uc3Qgc2VjdGlvbnM9W3tpZDonaGVybycsYTonSG9tZSd9LHtpZDoncm9vbXMtd3JhcCcsYTonU3RheSd9XTsKY29uc3QgbmF2TGlua3M9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLm5hdi1saW5rcyBhJyk7CndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCgpPT57CiAgY29uc3QgeT13aW5kb3cuc2Nyb2xsWSsxMjA7CiAgbmF2TGlua3MuZm9yRWFjaChhPT5hLnN0eWxlLmNvbG9yPScnKTsKfSx7cGFzc2l2ZTp0cnVlfSk7CgoKCihmdW5jdGlvbigpewogIHZhciBoYW09ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25hdkhhbScpOwogIHZhciBubD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubmF2LWxpbmtzJyk7CiAgaWYoIWhhbXx8IW5sKXJldHVybjsKICBoYW0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKCl7CiAgICBubC5jbGFzc0xpc3QudG9nZ2xlKCdvcGVuJyk7aGFtLmNsYXNzTGlzdC50b2dnbGUoJ29wZW4nKTsKICAgIGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3c9bmwuY2xhc3NMaXN0LmNvbnRhaW5zKCdvcGVuJyk/J2hpZGRlbic6Jyc7CiAgfSk7CiAgbmwucXVlcnlTZWxlY3RvckFsbCgnYScpLmZvckVhY2goZnVuY3Rpb24oYSl7CiAgICBhLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJyxmdW5jdGlvbigpewogICAgICBubC5jbGFzc0xpc3QucmVtb3ZlKCdvcGVuJyk7aGFtLmNsYXNzTGlzdC5yZW1vdmUoJ29wZW4nKTsKICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5vdmVyZmxvdz0nJzsKICAgIH0pOwogIH0pOwp9KSgpOwo8L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+Cgo='));
        $home_html = str_replace('<title>Mosaic Hostel — Classy Design</title>', '<title>Mosaic Hostel Varanasi — Near Assi Ghat</title>', $home_html);
        echo mosaic_inject_seo($home_html, 'home');
        exit;
    }
}, 1);
<?php

echo <<<'EOF'
<footer>
  <div class="footer-top">
    <img loading="lazy" src="https://www.mosaichostels.com/wp-content/uploads/2025/08/Logo-Transperent.webp" alt="Mosaic Hostel" style="height:110px;width:auto;filter:brightness(0) invert(1);opacity:0.9;">
    <div class="footer-links-wrap">
      <div class="footer-links">
        <div class="footer-heading">Explore</div>
        <a href="https://www.mosaichostels.com/gallery/">Gallery</a>
        <a href="https://www.mosaichostels.com/about/">About Us</a>
        <a href="#">Experiences</a>
        <a href="https://www.mosaichostels.com/contact/">Contact</a>
      </div>
      <div class="footer-links">
        <div class="footer-heading">Connect</div>
        <a href="https://wa.me/919125492225" target="_blank">WhatsApp</a>
        <a href="mailto:mosaichostels@gmail.com">Email Us</a>
        <a href="https://www.instagram.com/mosaichostels" target="_blank">Instagram</a>
      </div>
    </div>
  </div>
  <div class="footer-bottom">
    <div class="footer-copy">© 2025 Mosaic Hostel Varanasi. All rights reserved.</div>
    <div class="footer-tile-strip" id="footerStrip"></div>
    <div class="footer-copy">Made with ♥ in Varanasi</div>
  </div>
</footer>

EOF;
<?php

echo <<<'ENDSCRIPT'
<script>
// ── COLOUR PALETTE (logo) ──
const PAL = {
  gold:   ['#C8860A','#E8B84B','#D4930F','#F0C060'],
  teal:   ['#1A6B7A','#2D9AAA','#0D4A55'],
  burg:   ['#8B1A1A','#A02020','#6B1010'],
  cobalt: ['#1A3A6B','#2A5A9B','#0D1A40'],
  brown:  ['#5C3A1E','#7A4F2A','#3A2010'],
  sage:   ['#3D6B3A','#2D5A2A'],
};
const LOGO_COLORS = ['#C8860A','#8B1A1A','#1A6B7A','#1A3A6B','#5C3A1E','#E8B84B','#3D6B3A','#A02020','#2D9AAA','#7A4F2A'];
function pick(arr){return arr[Math.floor(Math.random()*arr.length)];}

// Fill a strip with logo colours
function fillStrip(id, colors){
  const el=document.getElementById(id);
  if(!el) return;
  colors.forEach(c=>{ const s=document.createElement('span'); s.style.flex='1'; s.style.background=c; el.appendChild(s); });
}
// Fill a small icon grid
function fillIcon(id, palette){
  const el=document.getElementById(id);
  if(!el) return;
  const n=el.style.gridTemplateColumns?el.style.gridTemplateColumns.match(/\d+px/g).length:3;
  const rows=el.style.gridTemplateRows?el.style.gridTemplateRows.match(/\d+px/g).length:3;
  const count=(n||3)*(rows||3);
  for(let i=0;i<count;i++){
    const s=document.createElement('span'); s.style.background=pick(palette); s.style.borderRadius='2px'; s.style.display='block'; el.appendChild(s);
  }
}

// Hero stripe
fillStrip('heroStripe', LOGO_COLORS);

// Hero tile icons
['heroTileL','heroTileR'].forEach(id=>{
  const el=document.getElementById(id);
  if(!el) return;
  LOGO_COLORS.slice(0,9).forEach(c=>{ const s=document.createElement('span'); s.style.background=c; s.style.borderRadius='1px'; el.appendChild(s); });
});

// Hero divider
fillStrip('heroDivider', ['#C8860A','#8B1A1A','#1A6B7A','#1A3A6B','#5C3A1E']);

// Dividers
['div1','div2','div3','div4'].forEach(id=>fillStrip(id, LOGO_COLORS));

// Title tile lines
['roomsTileLine','galTileLine','testiTileLine'].forEach(id=>fillStrip(id, ['#C8860A','#8B1A1A','#1A6B7A','#1A3A6B','#5C3A1E']));

// Room accent bars
const roomPals=[
  [...PAL.gold,...PAL.teal],
  [...PAL.teal,...PAL.cobalt],
  [...PAL.burg,...PAL.gold],
  [...PAL.cobalt,...PAL.sage],
  [...PAL.sage,...PAL.gold],
];
[1,2,3,4,5].forEach(i=>{
  const el=document.getElementById('ra'+i);
  if(!el) return;
  const pal=roomPals[(i-1)%roomPals.length];
  for(let k=0;k<20;k++){const s=document.createElement('span');s.style.flex='1';s.style.background=pick(pal);el.appendChild(s);}
});

// Philosophy icons (4×4)
[['pt1',PAL.gold,...PAL.teal],['pt2',...PAL.burg,...PAL.cobalt],['pt3',...PAL.sage,...PAL.gold]].forEach(([id,...pal])=>{
  const el=document.getElementById(id);
  if(!el) return;
  for(let i=0;i<16;i++){const s=document.createElement('span');s.style.background=pick(pal);s.style.borderRadius='2px';s.style.display='block';el.appendChild(s);}
});

// Experience strip
fillStrip('expStrip', LOGO_COLORS);

// Gallery left border already CSS

// Testimonial accent bars
[['ta1',PAL.gold,PAL.teal],['ta2',PAL.burg,PAL.cobalt],['ta3',PAL.sage,PAL.gold]].forEach(([id,p1,p2])=>{
  const el=document.getElementById(id);
  if(!el) return;
  for(let k=0;k<20;k++){const s=document.createElement('span');s.style.flex='1';s.style.background=pick([...p1,...p2]);el.appendChild(s);}
});

// Booking stripe — full rainbow
fillStrip('bookStripe', [...LOGO_COLORS,...LOGO_COLORS]);

// Footer strip
fillStrip('footerStrip', ['#C8860A','#8B1A1A','#1A6B7A','#1A3A6B','#3D6B3A']);

// ── CUSTOM CURSOR ──
const cur=document.getElementById('cursor');
const ring=document.getElementById('cursor-ring');
document.addEventListener('mousemove',e=>{
  cur.style.left=e.clientX+'px'; cur.style.top=e.clientY+'px';
  ring.style.left=e.clientX+'px'; ring.style.top=e.clientY+'px';
});
document.querySelectorAll('a,button,.room-card,.gal-item').forEach(el=>{
  el.addEventListener('mouseenter',()=>{
    cur.style.width='20px'; cur.style.height='20px';
    ring.style.width='50px'; ring.style.height='50px';
  });
  el.addEventListener('mouseleave',()=>{
    cur.style.width='10px'; cur.style.height='10px';
    ring.style.width='36px'; ring.style.height='36px';
  });
});

// ── NAV SCROLL ──
const nav=document.getElementById('mainNav');
window.addEventListener('scroll',()=>{
  nav.classList.toggle('scrolled', window.scrollY>80);
});

// ── SCROLL REVEAL ──
const observer=new IntersectionObserver(entries=>{
  entries.forEach(e=>{ if(e.isIntersecting) e.target.classList.add('visible'); });
},{threshold:0.12});
document.querySelectorAll('.reveal').forEach(el=>observer.observe(el));

// ── PARALLAX on experience photo ──
const expPhoto=document.getElementById('expPhoto');
window.addEventListener('scroll',()=>{
  if(!expPhoto) return;
  const rect=expPhoto.closest('.experience').getBoundingClientRect();
  const pct=(window.innerHeight-rect.top)/(window.innerHeight+rect.height);
  expPhoto.style.transform=`translateY(${(pct-0.5)*40}px)`;
},{passive:true});

// ── SCROLL PROGRESS BAR ──
const progressBar=document.createElement('div');
progressBar.style.cssText='position:fixed;top:0;left:0;height:3px;background:linear-gradient(90deg,#C8860A,#8B1A1A,#1A6B7A);z-index:9999;width:0%;transition:width 0.1s;pointer-events:none;';
document.body.appendChild(progressBar);
window.addEventListener('scroll',()=>{
  const pct=(window.scrollY/(document.body.scrollHeight-window.innerHeight))*100;
  progressBar.style.width=pct+'%';
},{passive:true});

// ── STAT COUNTER ANIMATION ──
const statNums=document.querySelectorAll('.stat-num');
const statObserver=new IntersectionObserver(entries=>{
  entries.forEach(entry=>{
    if(!entry.isIntersecting) return;
    const el=entry.target;
    const text=el.textContent;
    const num=parseFloat(text.replace(/[^0-9.]/g,''));
    if(!num||text.includes('★')||text.includes('Est')) return;
    const suffix=text.replace(/[\d.]/g,'');
    let start=0; const dur=1800;
    const step=ts=>{
      if(!start) start=ts;
      const prog=Math.min((ts-start)/dur,1);
      const ease=1-Math.pow(1-prog,3);
      el.textContent=Math.round(ease*num)+suffix;
      if(prog<1) requestAnimationFrame(step);
    };
    requestAnimationFrame(step);
    statObserver.unobserve(el);
  });
},{threshold:0.5});
statNums.forEach(el=>statObserver.observe(el));

// ── 3D TILT on room cards ──
document.querySelectorAll('.room-card').forEach(card=>{
  card.addEventListener('mousemove',e=>{
    const rect=card.getBoundingClientRect();
    const x=((e.clientX-rect.left)/rect.width-0.5)*12;
    const y=((e.clientY-rect.top)/rect.height-0.5)*-12;
    card.style.transform=`perspective(800px) rotateY(${x}deg) rotateX(${y}deg) scale(1.02)`;
    card.style.transition='transform 0.1s';
  });
  card.addEventListener('mouseleave',()=>{
    card.style.transform='perspective(800px) rotateY(0) rotateX(0) scale(1)';
    card.style.transition='transform 0.4s ease';
  });
});

// ── MAGNETIC BUTTONS ──
document.querySelectorAll('.btn-gold,.btn-primary,.hero-cta,.nav-book').forEach(btn=>{
  btn.addEventListener('mousemove',e=>{
    const rect=btn.getBoundingClientRect();
    const x=(e.clientX-rect.left-rect.width/2)*0.25;
    const y=(e.clientY-rect.top-rect.height/2)*0.25;
    btn.style.transform=`translate(${x}px,${y}px)`;
    btn.style.transition='transform 0.1s';
  });
  btn.addEventListener('mouseleave',()=>{
    btn.style.transform='translate(0,0)';
    btn.style.transition='transform 0.4s ease';
  });
});

// ── RIPPLE on buttons ──
document.querySelectorAll('.btn-gold,.btn-primary,.hero-cta,.nav-book').forEach(btn=>{
  btn.style.overflow='hidden';btn.style.position='relative';
  btn.addEventListener('click',e=>{
    const r=document.createElement('span');
    const rect=btn.getBoundingClientRect();
    const size=Math.max(rect.width,rect.height)*2;
    r.style.cssText=`position:absolute;width:${size}px;height:${size}px;border-radius:50%;background:rgba(255,255,255,0.25);transform:translate(-50%,-50%) scale(0);left:${e.clientX-rect.left}px;top:${e.clientY-rect.top}px;animation:ripple 0.6s ease-out forwards;pointer-events:none;`;
    btn.appendChild(r);
    setTimeout(()=>r.remove(),700);
  });
});
const rippleStyle=document.createElement('style');
rippleStyle.textContent='@keyframes ripple{to{transform:translate(-50%,-50%) scale(1);opacity:0;}}';
document.head.appendChild(rippleStyle);

// ── ACTIVE NAV LINK on scroll ──
const sections=[{id:'hero',a:'Home'},{id:'rooms-wrap',a:'Stay'}];
const navLinks=document.querySelectorAll('.nav-links a');
window.addEventListener('scroll',()=>{
  const y=window.scrollY+120;
  navLinks.forEach(a=>a.style.color='');
},{passive:true});



(function(){
  var ham=document.getElementById('navHam');
  var nl=document.querySelector('.nav-links');
  if(!ham||!nl)return;
  ham.addEventListener('click',function(){
    nl.classList.toggle('open');ham.classList.toggle('open');
    document.body.style.overflow=nl.classList.contains('open')?'hidden':'';
  });
  nl.querySelectorAll('a').forEach(function(a){
    a.addEventListener('click',function(){
      nl.classList.remove('open');ham.classList.remove('open');
      document.body.style.overflow='';
    });
  });
})();

</script>
ENDSCRIPT;