{"id":26,"date":"2024-12-11T14:53:09","date_gmt":"2024-12-11T14:53:09","guid":{"rendered":"https:\/\/rentamac.io\/?page_id=26"},"modified":"2026-09-01T15:08:11","modified_gmt":"2026-09-01T15:08:11","slug":"%d8%a7%d9%84%d8%aa%d8%b3%d8%b9%d9%8a%d8%b1","status":"publish","type":"page","link":"https:\/\/rentamac.io\/ar\/pricing\/","title":{"rendered":"\u0627\u0644\u062a\u0633\u0639\u064a\u0631"},"content":{"rendered":"\n<!-- RentaMac Pricing Component for WordPress -->\n<!-- Add this to your theme's functions.php or use a plugin to load Inter font:\n     wp_enqueue_style('google-fonts-inter', 'https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700;800&display=swap');\n-->\n<style>\n    \/* ============================================\n       CONFIGURATION - Easy to modify pricing\n       ============================================ *\/\n\n    .rentamac-pricing {\n      \/* Colors *\/\n      --bg: #0a0a0f;\n      --bg-card: rgba(255, 255, 255, 0.03);\n      --bg-card-hover: rgba(255, 255, 255, 0.05);\n      --stroke: rgba(255, 255, 255, 0.08);\n      --stroke-hover: rgba(255, 255, 255, 0.15);\n      --text: #f0f2f5;\n      --text-secondary: #8b919e;\n      --text-muted: #5c6370;\n\n      \/* Accent colors *\/\n      --accent-blue: #3b82f6;\n      --accent-blue-glow: rgba(59, 130, 246, 0.2);\n      --accent-purple: #a855f7;\n      --accent-green: #22c55e;\n      --accent-green-glow: rgba(34, 197, 94, 0.15);\n      --accent-orange: #f97316;\n\n      \/* Gradients *\/\n      --gradient-primary: linear-gradient(135deg, #3b82f6, #8b5cf6);\n      --gradient-success: linear-gradient(135deg, #22c55e, #10b981);\n\n      \/* Shadows *\/\n      --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);\n      --shadow-md: 0 8px 32px rgba(0, 0, 0, 0.4);\n      --shadow-lg: 0 16px 64px rgba(0, 0, 0, 0.5);\n      --shadow-glow: 0 0 40px var(--accent-blue-glow);\n\n      \/* Base styles for the component *\/\n      font-family: 'Inter', system-ui, -apple-system, sans-serif;\n      color: var(--text);\n      -webkit-font-smoothing: antialiased;\n      line-height: 1.5;\n      box-sizing: border-box;\n    }\n\n    .rentamac-pricing *,\n    .rentamac-pricing *::before,\n    .rentamac-pricing *::after {\n      box-sizing: border-box;\n    }\n\n    \/* Container *\/\n    .rentamac-pricing .container {\n      max-width: 720px;\n      margin: 0 auto;\n      padding: 4px 24px 24px;\n    }\n\n    \/* Header *\/\n    .rentamac-pricing .header {\n      text-align: center;\n      margin-top: 0;\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .header h1 {\n      font-size: clamp(32px, 5vw, 48px);\n      font-weight: 800;\n      letter-spacing: -0.5px;\n      margin-top: 0;\n      margin-bottom: 10px;\n      color: #ffffff; \/* White fallback color for browsers that don't support gradient text *\/\n    }\n\n    @supports (-webkit-background-clip: text) or (background-clip: text) {\n      .rentamac-pricing .header h1 {\n        background: linear-gradient(135deg, #ffffff 0%, rgba(255, 255, 255, 0.8) 100%);\n        -webkit-background-clip: text;\n        -webkit-text-fill-color: transparent;\n        background-clip: text;\n      }\n    }\n\n    \/* Main Card *\/\n    .rentamac-pricing .pricing-card {\n      background: var(--bg);\n      border: 1px solid var(--stroke);\n      border-radius: 24px;\n      padding: 24px 32px 32px;\n      box-shadow: var(--shadow-lg);\n    }\n\n    \/* Device Info *\/\n    .rentamac-pricing .device-info {\n      display: flex;\n      align-items: center;\n      gap: 6px;\n      padding-bottom: 10px;\n      border-bottom: 1px solid var(--stroke);\n      margin-bottom: 10px;\n    }\n\n    .rentamac-pricing .device-image {\n      width: 100px;\n      height: 56px;\n      object-fit: contain;\n      filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.4));\n    }\n\n    .rentamac-pricing .device-details h2 {\n      font-size: 22px;\n      font-weight: 700;\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .device-specs {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 8px;\n    }\n\n    .rentamac-pricing .spec-badge {\n      background: rgba(255, 255, 255, 0.06);\n      border: 1px solid var(--stroke);\n      border-radius: 6px;\n      padding: 4px 10px;\n      font-size: 12px;\n      font-weight: 500;\n      color: var(--text-secondary);\n      display: inline-flex;\n      align-items: center;\n      gap: 4px;\n      position: relative;\n    }\n\n    .rentamac-pricing .spec-badge .feature-info {\n      width: 14px;\n      height: 14px;\n      margin-left: 2px;\n    }\n\n    .rentamac-pricing .spec-badge .feature-info svg {\n      width: 12px;\n      height: 12px;\n      color: var(--text-muted);\n    }\n\n    .rentamac-pricing .spec-badge .feature-info:hover svg {\n      color: var(--accent-blue);\n    }\n\n    .rentamac-pricing .spec-badge .feature-info .tooltip {\n      width: 240px;\n      left: 50%;\n      transform: translateX(-50%);\n    }\n\n    .rentamac-pricing .spec-badge {\n      cursor: help;\n    }\n\n    .rentamac-pricing .spec-badge:hover .feature-info svg {\n      color: var(--accent-blue);\n    }\n\n    .rentamac-pricing .spec-badge:hover .feature-info .tooltip {\n      opacity: 1;\n      visibility: visible;\n    }\n\n    \/* Section Titles *\/\n    .rentamac-pricing .section-title {\n      font-size: 13px;\n      font-weight: 600;\n      color: var(--text-muted);\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      margin-bottom: 3px;\n    }\n\n    \/* Cycle Selector *\/\n    .rentamac-pricing .cycle-section {\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .cycle-tabs {\n      display: flex;\n      gap: 4px;\n      flex-wrap: wrap;\n    }\n\n    .rentamac-pricing .cycle-tab {\n      flex: 1;\n      min-width: 80px;\n      background: rgba(255, 255, 255, 0.04);\n      border: 1px solid var(--stroke);\n      border-radius: 12px;\n      padding: 14px 12px;\n      cursor: pointer;\n      transition: all 0.2s ease;\n      text-align: center;\n      position: relative;\n    }\n\n    .rentamac-pricing .cycle-tab:hover {\n      background: rgba(255, 255, 255, 0.06);\n      border-color: var(--stroke-hover);\n    }\n\n    .rentamac-pricing .cycle-tab.active {\n      background: rgba(59, 130, 246, 0.1);\n      border-color: var(--accent-blue);\n      box-shadow: 0 0 20px var(--accent-blue-glow);\n    }\n\n    .rentamac-pricing .cycle-tab .cycle-name {\n      font-size: 14px;\n      font-weight: 600;\n      color: var(--text);\n      display: block;\n      margin-top: 6px;\n      margin-bottom: 2px;\n    }\n\n    .rentamac-pricing .cycle-tab .cycle-price {\n      font-size: 12px;\n      color: var(--text-secondary);\n    }\n\n    .rentamac-pricing .cycle-tab.active .cycle-name {\n      color: var(--accent-blue);\n    }\n\n    .rentamac-pricing .cycle-tab .savings-badge {\n      display: inline-block;\n      background: var(--gradient-success);\n      color: #000;\n      font-size: 10px;\n      font-weight: 700;\n      padding: 2px 6px;\n      border-radius: 4px;\n      margin-top: 6px;\n    }\n\n    .rentamac-pricing .cycle-tab .popular-badge {\n      position: absolute;\n      top: -8px;\n      left: 50%;\n      transform: translateX(-50%);\n      background: var(--accent-blue);\n      color: #fff;\n      font-size: 9px;\n      font-weight: 700;\n      padding: 3px 8px;\n      border-radius: 4px;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n    }\n\n    \/* Unavailable cycle tab (e.g. daily plan low stock) *\/\n    .rentamac-pricing .cycle-tab.unavailable {\n      cursor: not-allowed;\n      position: relative;\n    }\n\n    .rentamac-pricing .cycle-tab.unavailable .cycle-name,\n    .rentamac-pricing .cycle-tab.unavailable .cycle-price {\n      opacity: 0.4;\n    }\n\n    .rentamac-pricing .cycle-tab.unavailable:hover {\n      background: rgba(255, 255, 255, 0.04);\n      border-color: var(--stroke);\n    }\n\n    .rentamac-pricing .cycle-tab.unavailable::after {\n      content: 'Disabled when availability is low. Join the waitlist to be notified.';\n      position: absolute;\n      bottom: 100%;\n      left: 50%;\n      transform: translateX(-50%);\n      background: var(--accent-orange);\n      color: #fff;\n      padding: 8px 14px;\n      border-radius: 8px;\n      font-size: 12px;\n      font-weight: 600;\n      white-space: nowrap;\n      opacity: 0;\n      visibility: hidden;\n      transition: all 0.2s ease;\n      pointer-events: none;\n      z-index: 10;\n      margin-bottom: 10px;\n    }\n\n    .rentamac-pricing .cycle-tab.unavailable::before {\n      content: '';\n      position: absolute;\n      bottom: 100%;\n      left: 50%;\n      transform: translateX(-50%);\n      border: 6px solid transparent;\n      border-top-color: var(--accent-orange);\n      opacity: 0;\n      visibility: hidden;\n      transition: all 0.2s ease;\n      margin-bottom: -2px;\n      z-index: 10;\n    }\n\n    .rentamac-pricing .cycle-tab.unavailable:hover::after,\n    .rentamac-pricing .cycle-tab.unavailable:hover::before {\n      opacity: 1;\n      visibility: visible;\n    }\n\n    \/* Region-aware tooltip text set from JS (falls back to the static copy above) *\/\n    .rentamac-pricing .cycle-tab.unavailable[data-tip]::after {\n      content: attr(data-tip);\n    }\n\n    \/* Location Section *\/\n    .rentamac-pricing .location-section {\n      margin-bottom: 4px;\n    }\n\n    \/* Storage Section *\/\n    .rentamac-pricing .storage-section {\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .storage-options {\n      display: flex;\n      gap: 5px;\n      flex-wrap: wrap;\n    }\n\n    .rentamac-pricing .storage-option {\n      flex: 1;\n      min-width: 140px;\n      background: rgba(255, 255, 255, 0.04);\n      border: 1px solid var(--stroke);\n      border-radius: 12px;\n      padding: 16px;\n      cursor: pointer;\n      transition: all 0.2s ease;\n      text-align: center;\n      position: relative;\n    }\n\n    .rentamac-pricing .storage-option:hover:not(.disabled) {\n      background: rgba(255, 255, 255, 0.06);\n      border-color: var(--stroke-hover);\n    }\n\n    .rentamac-pricing .storage-option.active {\n      background: rgba(34, 197, 94, 0.08);\n      border-color: var(--accent-green);\n    }\n\n    .rentamac-pricing .storage-option.disabled {\n      cursor: not-allowed;\n    }\n    .rentamac-pricing .storage-option.disabled .storage-content {\n      opacity: 0.6;\n      filter: blur(1.5px);\n    }\n    .rentamac-pricing .storage-option.disabled:hover .storage-content {\n      filter: blur(1px);\n    }\n    .rentamac-pricing .storage-option.disabled::after {\n      content: 'Storage add-ons are only available on weekly or higher plans';\n      position: absolute;\n      bottom: 100%;\n      left: 50%;\n      transform: translateX(-50%);\n      background: rgba(0, 0, 0, 0.9);\n      color: var(--text);\n      padding: 8px 12px;\n      border-radius: 8px;\n      font-size: 12px;\n      font-weight: 500;\n      white-space: nowrap;\n      opacity: 0;\n      visibility: hidden;\n      transition: all 0.2s ease;\n      pointer-events: none;\n      z-index: 10;\n      margin-bottom: 8px;\n      border: 1px solid var(--stroke);\n    }\n    .rentamac-pricing .storage-option.disabled::before {\n      content: '';\n      position: absolute;\n      bottom: 100%;\n      left: 50%;\n      transform: translateX(-50%);\n      border: 6px solid transparent;\n      border-top-color: rgba(0, 0, 0, 0.9);\n      opacity: 0;\n      visibility: hidden;\n      transition: all 0.2s ease;\n      margin-bottom: 2px;\n    }\n    .rentamac-pricing .storage-option.disabled:hover::after,\n    .rentamac-pricing .storage-option.disabled:hover::before {\n      opacity: 1;\n      visibility: visible;\n    }\n\n    .rentamac-pricing .storage-option.unavailable {\n      cursor: not-allowed;\n      position: relative;\n    }\n\n    .rentamac-pricing .storage-option.unavailable .storage-content {\n      opacity: 0.6;\n      filter: blur(1.5px);\n    }\n\n    .rentamac-pricing .storage-option.unavailable:hover .storage-content {\n      filter: blur(1px);\n    }\n\n    .rentamac-pricing .storage-option.unavailable::after {\n      content: 'Unavailable due to high demand';\n      position: absolute;\n      bottom: 100%;\n      left: 50%;\n      transform: translateX(-50%);\n      background: rgba(0, 0, 0, 0.9);\n      color: var(--text);\n      padding: 8px 12px;\n      border-radius: 8px;\n      font-size: 12px;\n      font-weight: 500;\n      white-space: nowrap;\n      opacity: 0;\n      visibility: hidden;\n      transition: all 0.2s ease;\n      pointer-events: none;\n      z-index: 10;\n      margin-bottom: 8px;\n      border: 1px solid var(--stroke);\n    }\n\n    .rentamac-pricing .storage-option.unavailable::before {\n      content: '';\n      position: absolute;\n      bottom: 100%;\n      left: 50%;\n      transform: translateX(-50%);\n      border: 6px solid transparent;\n      border-top-color: rgba(0, 0, 0, 0.9);\n      opacity: 0;\n      visibility: hidden;\n      transition: all 0.2s ease;\n      margin-bottom: 2px;\n    }\n\n    .rentamac-pricing .storage-option.unavailable:hover::after,\n    .rentamac-pricing .storage-option.unavailable:hover::before {\n      opacity: 1;\n      visibility: visible;\n    }\n\n    \/* Region-aware tooltip text set from JS (falls back to the static copy above) *\/\n    .rentamac-pricing .storage-option.unavailable[data-tip]::after {\n      content: attr(data-tip);\n    }\n\n\n    .rentamac-pricing .storage-option .storage-size {\n      font-size: 18px;\n      font-weight: 700;\n      color: var(--text);\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .storage-option.active .storage-size {\n      color: var(--accent-green);\n    }\n\n    .rentamac-pricing .storage-option .storage-label {\n      font-size: 12px;\n      color: var(--text-secondary);\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .storage-option .storage-sublabel {\n      font-size: 10px;\n      color: var(--text-muted);\n      margin-bottom: 6px;\n      text-transform: uppercase;\n      letter-spacing: 0.3px;\n    }\n\n    .rentamac-pricing .storage-option .storage-price {\n      font-size: 13px;\n      font-weight: 600;\n      color: var(--text-muted);\n    }\n\n    .rentamac-pricing .storage-option.active .storage-price {\n      color: var(--accent-green);\n    }\n\n    .rentamac-pricing .storage-option .default-badge {\n      position: absolute;\n      top: -8px;\n      right: 12px;\n      background: var(--accent-blue);\n      color: #fff;\n      font-size: 9px;\n      font-weight: 700;\n      padding: 3px 8px;\n      border-radius: 4px;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n    }\n\n    \/* Features List *\/\n    .rentamac-pricing .features-section {\n      margin-bottom: 4px;\n      padding-top: 10px;\n    }\n\n    .rentamac-pricing .features-grid {\n      display: grid;\n      grid-template-columns: repeat(2, 1fr);\n      gap: 6px;\n    }\n\n    @media (max-width: 500px) {\n      .rentamac-pricing .features-grid {\n        grid-template-columns: 1fr;\n      }\n    }\n\n    .rentamac-pricing .feature-item {\n      display: flex;\n      align-items: center;\n      gap: 10px;\n      font-size: 14px;\n      color: var(--text-secondary);\n      cursor: help;\n    }\n\n    .rentamac-pricing .feature-item:hover .feature-info svg {\n      color: var(--accent-blue);\n    }\n\n    .rentamac-pricing .feature-item:hover .feature-info .tooltip {\n      opacity: 1;\n      visibility: visible;\n    }\n\n    .rentamac-pricing .feature-icon {\n      width: 20px;\n      height: 20px;\n      border-radius: 6px;\n      background: rgba(34, 197, 94, 0.15);\n      border: 1px solid rgba(34, 197, 94, 0.3);\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      color: var(--accent-green);\n      font-size: 11px;\n      flex-shrink: 0;\n    }\n\n    \/* Info icon tooltip styles *\/\n    .rentamac-pricing .feature-info {\n      position: relative;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      width: 16px;\n      height: 16px;\n      margin-left: 6px;\n      cursor: help;\n      flex-shrink: 0;\n    }\n\n    .rentamac-pricing .feature-info svg {\n      width: 14px;\n      height: 14px;\n      color: var(--text-muted);\n      transition: color 0.2s ease;\n    }\n\n    .rentamac-pricing .feature-info:hover svg {\n      color: var(--accent-blue);\n    }\n\n    .rentamac-pricing .feature-info .tooltip {\n      position: absolute;\n      bottom: calc(100% + 8px);\n      left: 50%;\n      transform: translateX(-50%);\n      background: rgba(15, 15, 20, 0.98);\n      border: 1px solid var(--stroke-hover);\n      border-radius: 10px;\n      padding: 12px 14px;\n      width: 260px;\n      font-size: 13px;\n      line-height: 1.5;\n      color: var(--text-secondary);\n      text-align: left;\n      opacity: 0;\n      visibility: hidden;\n      transition: all 0.2s ease;\n      pointer-events: none;\n      z-index: 100;\n      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);\n    }\n\n    .rentamac-pricing .feature-info .tooltip::after {\n      content: '';\n      position: absolute;\n      top: 100%;\n      left: 50%;\n      transform: translateX(-50%);\n      border: 6px solid transparent;\n      border-top-color: rgba(15, 15, 20, 0.98);\n    }\n\n    .rentamac-pricing .feature-info:hover .tooltip {\n      opacity: 1;\n      visibility: visible;\n    }\n\n    @media (max-width: 600px) {\n      .rentamac-pricing .feature-info .tooltip {\n        width: 220px;\n        left: auto;\n        right: -10px;\n        transform: none;\n      }\n\n      .rentamac-pricing .feature-info .tooltip::after {\n        left: auto;\n        right: 16px;\n        transform: none;\n      }\n    }\n\n    \/* Price Display *\/\n    .rentamac-pricing .price-section {\n      text-align: center;\n      padding: 10px 0;\n      border-bottom: 1px solid var(--stroke);\n      margin-bottom: 10px;\n    }\n\n    .rentamac-pricing .total-label {\n      font-size: 13px;\n      color: var(--text-muted);\n      margin-bottom: 8px;\n    }\n\n    .rentamac-pricing .total-price {\n      font-size: 52px;\n      font-weight: 800;\n      letter-spacing: -2px;\n      margin-bottom: 8px;\n      color: var(--text);\n    }\n\n    .rentamac-pricing .price-breakdown {\n      font-size: 15px;\n      color: var(--text-secondary);\n    }\n\n    .rentamac-pricing .storage-addon-note {\n      font-size: 13px;\n      color: var(--text-muted);\n      margin-top: 8px;\n    }\n\n    \/* CTA Button *\/\n    .rentamac-pricing .cta-button {\n      width: 100%;\n      padding: 18px 24px;\n      font-size: 17px;\n      font-weight: 700;\n      border: none;\n      border-radius: 14px;\n      cursor: pointer;\n      background: var(--accent-blue);\n      color: white;\n      transition: all 0.2s ease;\n      box-shadow: var(--shadow-md), 0 0 30px var(--accent-blue-glow);\n    }\n\n    .rentamac-pricing .cta-button:hover {\n      transform: translateY(-2px);\n      box-shadow: var(--shadow-lg), 0 0 50px var(--accent-blue-glow);\n    }\n\n    .rentamac-pricing .cta-button:active {\n      transform: translateY(0);\n    }\n\n    .rentamac-pricing .cta-button:disabled {\n      opacity: 0.65;\n      cursor: default;\n      transform: none;\n      box-shadow: none;\n    }\n\n    .rentamac-pricing .checkout-error {\n      margin-top: 12px;\n      font-size: 14px;\n      line-height: 1.4;\n      text-align: center;\n      color: #f87171;\n    }\n\n    \/* Help Text *\/\n    .rentamac-pricing .help-text {\n      text-align: center;\n      margin-top: 20px;\n      font-size: 14px;\n      color: var(--text-muted);\n    }\n\n    .rentamac-pricing .help-text a {\n      color: var(--accent-blue);\n      text-decoration: none;\n    }\n\n    .rentamac-pricing .help-text a:hover {\n      text-decoration: underline;\n    }\n\n    \/* Animations *\/\n    @keyframes rentamacFadeIn {\n      from { opacity: 0; transform: translateY(10px); }\n      to { opacity: 1; transform: translateY(0); }\n    }\n\n    .rentamac-pricing .pricing-card {\n      animation: rentamacFadeIn 0.4s ease-out;\n    }\n\n    \/* Responsive *\/\n    @media (max-width: 600px) {\n      .rentamac-pricing .container {\n        padding: 32px 16px;\n      }\n\n      .rentamac-pricing .pricing-card {\n        padding: 24px 20px;\n      }\n\n      .rentamac-pricing .device-info {\n        flex-direction: column;\n        text-align: center;\n      }\n\n      .rentamac-pricing .device-specs {\n        justify-content: center;\n      }\n\n      .rentamac-pricing .cycle-tabs {\n        flex-wrap: wrap;\n      }\n\n      .rentamac-pricing .cycle-tab {\n        min-width: calc(33.333% - 6px);\n        padding: 12px 8px;\n      }\n\n      .rentamac-pricing .cycle-tab.unavailable::after {\n        white-space: normal;\n        width: 220px;\n        text-align: center;\n      }\n\n      .rentamac-pricing .storage-option.unavailable::after {\n        white-space: normal;\n        width: 220px;\n        text-align: center;\n      }\n\n      .rentamac-pricing .total-price {\n        font-size: 42px;\n      }\n    }\n\n    \/* Compact layout for short viewports (e.g. 1080x720) *\/\n    @media (max-height: 820px) {\n      .rentamac-pricing .container {\n        padding-top: 0;\n      }\n\n      .rentamac-pricing .header {\n        margin-bottom: 2px;\n      }\n\n      .rentamac-pricing .header h1 {\n        font-size: clamp(24px, 4vw, 36px);\n        margin-bottom: 2px;\n      }\n\n      .rentamac-pricing .pricing-card {\n        padding: 20px 28px;\n      }\n\n      .rentamac-pricing .device-info {\n        padding-bottom: 6px;\n        margin-bottom: 6px;\n      }\n\n      .rentamac-pricing .cycle-section {\n        margin-bottom: 2px;\n      }\n\n      .rentamac-pricing .cycle-tab {\n        padding: 10px 10px;\n      }\n\n      .rentamac-pricing .storage-section {\n        margin-bottom: 2px;\n      }\n\n      .rentamac-pricing .storage-option {\n        padding: 10px;\n      }\n\n      .rentamac-pricing .features-section {\n        margin-bottom: 2px;\n        padding-top: 6px;\n      }\n\n      .rentamac-pricing .features-grid {\n        gap: 2px;\n      }\n\n      .rentamac-pricing .price-section {\n        padding: 6px 0;\n        margin-bottom: 6px;\n      }\n\n      .rentamac-pricing .total-price {\n        font-size: 40px;\n        margin-bottom: 4px;\n      }\n\n      .rentamac-pricing .total-label {\n        margin-bottom: 4px;\n      }\n\n      .rentamac-pricing .cta-button {\n        padding: 14px 24px;\n      }\n    }\n\n    \/* No storage available message *\/\n    .rentamac-pricing .no-storage-message {\n      background: rgba(249, 115, 22, 0.1);\n      border: 1px solid rgba(249, 115, 22, 0.2);\n      border-radius: 10px;\n      padding: 12px 16px;\n      text-align: center;\n      color: var(--accent-orange);\n      font-size: 13px;\n      font-weight: 500;\n    }\n\n    .rentamac-pricing .storage-addon-disabled-note {\n      display: none !important;\n    }\n\n    \/* Availability Dialog *\/\n    .rentamac-pricing .availability-overlay {\n      position: fixed;\n      inset: 0;\n      background: rgba(0, 0, 0, 0.7);\n      backdrop-filter: blur(8px);\n      z-index: 1000;\n      animation: rentamacFadeIn 0.25s ease-out forwards;\n    }\n\n    .rentamac-pricing .availability-dialog {\n      position: fixed;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      background: var(--bg);\n      border: 1px solid var(--stroke);\n      border-radius: 20px;\n      padding: 32px;\n      max-width: 480px;\n      width: calc(100% - 48px);\n      z-index: 1010;\n      animation: rentamacDialogSlide 0.3s ease-out forwards;\n    }\n\n    @keyframes rentamacDialogSlide {\n      from { opacity: 0; transform: translate(-50%, calc(-50% - 20px)); }\n      to { opacity: 1; transform: translate(-50%, -50%); }\n    }\n\n    .rentamac-pricing .availability-dialog__header {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin-bottom: 16px;\n    }\n\n    .rentamac-pricing .availability-dialog__title {\n      font-size: 22px;\n      font-weight: 700;\n      color: var(--text);\n      margin: 0;\n    }\n\n    .rentamac-pricing .availability-dialog__close {\n      background: transparent;\n      border: none;\n      color: var(--text-secondary);\n      font-size: 24px;\n      cursor: pointer;\n      transition: color 0.2s ease;\n      line-height: 1;\n    }\n\n    .rentamac-pricing .availability-dialog__close:hover {\n      color: var(--text);\n    }\n\n    .rentamac-pricing .availability-dialog p {\n      color: var(--text-secondary);\n      line-height: 1.6;\n      margin: 0 0 20px;\n    }\n\n    .rentamac-pricing .availability-form {\n      display: flex;\n      gap: 12px;\n      flex-wrap: wrap;\n    }\n\n    .rentamac-pricing .availability-form input[type=\"email\"] {\n      flex: 1;\n      min-width: 200px;\n      padding: 14px 16px;\n      border-radius: 12px;\n      border: 1px solid var(--stroke);\n      background: rgba(0, 0, 0, 0.3);\n      color: var(--text);\n      font-size: 15px;\n      outline: none;\n      transition: border-color 0.2s ease;\n    }\n\n    .rentamac-pricing .availability-form input[type=\"email\"]:focus {\n      border-color: var(--accent-blue);\n    }\n\n    .rentamac-pricing .availability-form button {\n      padding: 14px 24px;\n      border-radius: 12px;\n      border: none;\n      background: var(--accent-blue);\n      color: white;\n      font-weight: 600;\n      font-size: 15px;\n      cursor: pointer;\n      transition: transform 0.2s ease, opacity 0.2s ease, box-shadow 0.2s ease;\n    }\n\n    .rentamac-pricing .availability-form button:hover {\n      transform: translateY(-1px);\n      box-shadow: 0 0 20px var(--accent-blue-glow);\n    }\n\n    .rentamac-pricing .availability-form button:disabled {\n      opacity: 0.6;\n      cursor: not-allowed;\n      transform: none;\n    }\n\n    .rentamac-pricing .availability-feedback {\n      width: 100%;\n      margin-top: 12px;\n      font-size: 14px;\n      min-height: 20px;\n    }\n\n    .rentamac-pricing .availability-feedback.success { color: var(--accent-green); }\n    .rentamac-pricing .availability-feedback.error { color: #ef4444; }\n    .rentamac-pricing .availability-feedback.info { color: var(--text-muted); }\n\n    .rentamac-pricing .availability-disclaimer {\n      font-size: 12px;\n      color: var(--text-muted);\n      margin-top: 16px;\n    }\n\n    .rentamac-pricing .is-hidden { display: none !important; }\n\n    .rentamac-pricing .sr-only {\n      position: absolute;\n      width: 1px;\n      height: 1px;\n      padding: 0;\n      margin: -1px;\n      overflow: hidden;\n      clip: rect(0, 0, 0, 0);\n      border: 0;\n    }\n\n    \/* Out of stock button state *\/\n    .rentamac-pricing .cta-button.out-of-stock {\n      background: rgba(255, 255, 255, 0.1);\n      box-shadow: none;\n    }\n\n    .rentamac-pricing .cta-button.out-of-stock:hover {\n      transform: none;\n      box-shadow: none;\n    }\n\n    \/* Cross-location availability notices (rendered from JS, hidden until the status API lands).\n       Same blue treatment as the active tab \/ CTA so they read as part of the card. *\/\n    .rentamac-pricing .availability-note {\n      display: flex;\n      align-items: flex-start;\n      gap: 10px;\n      margin-top: 12px;\n      padding: 12px 14px;\n      border: 1px solid rgba(59, 130, 246, 0.4);\n      border-radius: 12px;\n      background: rgba(59, 130, 246, 0.1);\n      color: var(--text);\n      font-size: 13px;\n      font-weight: 500;\n      line-height: 1.5;\n      text-align: left;\n    }\n\n    .rentamac-pricing .availability-note.is-warning {\n      border-color: rgba(59, 130, 246, 0.55);\n      background: rgba(59, 130, 246, 0.14);\n    }\n\n    .rentamac-pricing .availability-note__icon {\n      flex: 0 0 auto;\n      width: 16px;\n      height: 16px;\n      margin-top: 2px;\n      color: #93c5fd;\n    }\n\n    .rentamac-pricing .availability-note a,\n    .rentamac-pricing .cta-alt-location a,\n    .rentamac-pricing .availability-alt a {\n      color: #93c5fd;\n      font-weight: 600;\n      text-decoration: underline;\n      text-underline-offset: 2px;\n      cursor: pointer;\n      transition: color 0.2s ease;\n    }\n\n    .rentamac-pricing .availability-note a:hover,\n    .rentamac-pricing .cta-alt-location a:hover,\n    .rentamac-pricing .availability-alt a:hover {\n      color: #fff;\n    }\n\n    .rentamac-pricing .cta-alt-location {\n      margin-top: 10px;\n      text-align: center;\n      font-size: 13px;\n      color: var(--text-secondary);\n    }\n\n    .rentamac-pricing .availability-alt {\n      display: flex;\n      flex-wrap: wrap;\n      align-items: center;\n      justify-content: space-between;\n      gap: 10px 12px;\n      margin: 0 0 20px;\n      padding: 12px 14px;\n      border: 1px solid rgba(59, 130, 246, 0.4);\n      border-radius: 12px;\n      background: rgba(59, 130, 246, 0.1);\n      color: var(--text);\n      font-size: 14px;\n      font-weight: 500;\n      line-height: 1.5;\n    }\n\n    .rentamac-pricing .availability-alt__actions {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 8px;\n    }\n\n    .rentamac-pricing .availability-alt button {\n      padding: 8px 14px;\n      border-radius: 10px;\n      border: none;\n      background: var(--accent-blue);\n      color: #fff;\n      font-weight: 600;\n      font-size: 13px;\n      white-space: nowrap;\n      cursor: pointer;\n      transition: transform 0.2s ease, box-shadow 0.2s ease;\n    }\n\n    .rentamac-pricing .availability-alt button:hover {\n      transform: translateY(-1px);\n      box-shadow: 0 0 20px var(--accent-blue-glow);\n    }\n\n    .rentamac-pricing .availability-note[hidden],\n    .rentamac-pricing .cta-alt-location[hidden],\n    .rentamac-pricing .availability-alt[hidden] {\n      display: none !important;\n    }\n\n\n    \/* Purchase Info Dropdown *\/\n    .rentamac-pricing .purchase-info {\n      margin-top: 32px;\n      text-align: center;\n    }\n\n    .rentamac-pricing .purchase-dropdown {\n      max-width: 480px;\n      margin: 0 auto;\n    }\n\n    .rentamac-pricing .purchase-dropdown-trigger {\n      width: 100%;\n      background: rgba(255, 255, 255, 0.06);\n      border: 1px solid var(--stroke);\n      border-radius: 12px;\n      padding: 16px 20px;\n      color: var(--text);\n      font-size: 15px;\n      font-weight: 600;\n      cursor: pointer;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      transition: all 0.2s ease;\n      position: relative;\n    }\n\n    .rentamac-pricing .purchase-dropdown-trigger:hover {\n      background: rgba(255, 255, 255, 0.08);\n      border-color: var(--stroke-hover);\n    }\n\n    .rentamac-pricing .purchase-dropdown-icon {\n      position: absolute;\n      right: 20px;\n      opacity: 0.6;\n      transition: transform 0.2s ease;\n    }\n\n    .rentamac-pricing .purchase-dropdown-trigger[aria-expanded=\"true\"] .purchase-dropdown-icon {\n      transform: rotate(180deg);\n    }\n\n    .rentamac-pricing .purchase-dropdown-content {\n      overflow: hidden;\n      max-height: 0;\n      opacity: 0;\n      transition: all 0.3s ease;\n      background: rgba(255, 255, 255, 0.04);\n      border: 1px solid var(--stroke);\n      border-top: none;\n      border-radius: 0 0 12px 12px;\n      margin-top: -1px;\n    }\n\n    .rentamac-pricing .purchase-dropdown-content.expanded {\n      max-height: 200px;\n      opacity: 1;\n      padding: 16px 20px;\n    }\n\n    .rentamac-pricing .purchase-dropdown-content p {\n      font-size: 14px;\n      color: var(--text-secondary);\n      margin: 0;\n      line-height: 1.6;\n      text-align: center;\n    }\n\n    \/* Help Section *\/\n    .rentamac-pricing .help-section {\n      margin-top: 64px;\n      text-align: center;\n    }\n\n    .rentamac-pricing .help-header {\n      margin-bottom: 40px;\n    }\n\n    .rentamac-pricing .help-header h3 {\n      font-size: 28px;\n      font-weight: 700;\n      margin: 0 0 8px;\n      color: var(--text);\n    }\n\n    .rentamac-pricing .help-subtitle {\n      font-size: 16px;\n      color: var(--text-secondary);\n      margin: 0;\n    }\n\n    .rentamac-pricing .help-cards {\n      display: grid;\n      grid-template-columns: repeat(2, 1fr);\n      gap: 24px;\n      max-width: 720px;\n      margin: 0 auto 48px;\n    }\n\n    @media (max-width: 600px) {\n      .rentamac-pricing .help-cards {\n        grid-template-columns: 1fr;\n        gap: 20px;\n      }\n    }\n\n    .rentamac-pricing .help-card {\n      background: var(--bg);\n      border: 1px solid var(--stroke);\n      border-radius: 20px;\n      padding: 32px 24px;\n      text-align: center;\n      transition: all 0.3s ease;\n      position: relative;\n      overflow: hidden;\n    }\n\n    .rentamac-pricing .help-card::before {\n      content: '';\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      height: 3px;\n      background: var(--gradient-primary);\n      opacity: 0;\n      transition: opacity 0.3s ease;\n    }\n\n    .rentamac-pricing .help-card:hover {\n      transform: translateY(-4px);\n      border-color: var(--stroke-hover);\n      box-shadow: var(--shadow-lg);\n    }\n\n    .rentamac-pricing .help-card:hover::before {\n      opacity: 1;\n    }\n\n    .rentamac-pricing .help-icon {\n      width: 56px;\n      height: 56px;\n      margin: 0 auto 20px;\n      background: rgba(255, 255, 255, 0.06);\n      border-radius: 16px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      color: var(--text);\n      transition: all 0.3s ease;\n    }\n\n    .rentamac-pricing .help-card:hover .help-icon {\n      background: rgba(255, 255, 255, 0.1);\n      transform: scale(1.05);\n    }\n\n    .rentamac-pricing .help-card h4 {\n      font-size: 20px;\n      font-weight: 700;\n      margin: 0 0 12px;\n      color: var(--text);\n    }\n\n    .rentamac-pricing .help-card p {\n      color: var(--text-secondary);\n      margin: 0 0 24px;\n      font-size: 14px;\n      line-height: 1.5;\n    }\n\n    .rentamac-pricing .help-btn {\n      border: none;\n      border-radius: 12px;\n      padding: 12px 24px;\n      font-weight: 600;\n      cursor: pointer;\n      font-size: 14px;\n      transition: all 0.2s ease;\n      display: inline-flex;\n      align-items: center;\n      gap: 8px;\n    }\n\n    .rentamac-pricing .help-btn.secondary {\n      background: rgba(255, 255, 255, 0.08);\n      color: var(--text);\n      border: 1px solid var(--stroke);\n    }\n\n    .rentamac-pricing .help-btn.secondary:hover {\n      background: rgba(255, 255, 255, 0.12);\n      transform: translateY(-2px);\n    }\n\n    .rentamac-pricing .help-footer {\n      margin-top: 48px;\n      padding-top: 40px;\n      border-top: 1px solid var(--stroke);\n    }\n\n    .rentamac-pricing .help-footer-text {\n      font-size: 16px;\n      color: var(--text-secondary);\n      margin: 0 0 20px;\n    }\n\n    .rentamac-pricing .help-portal-btn {\n      background: rgba(255, 255, 255, 0.06);\n      color: var(--text);\n      border: 1px solid var(--stroke);\n      border-radius: 14px;\n      padding: 14px 24px;\n      font-weight: 600;\n      font-size: 15px;\n      cursor: pointer;\n      transition: all 0.2s ease;\n      display: inline-flex;\n      align-items: center;\n      gap: 10px;\n    }\n\n    .rentamac-pricing .help-portal-btn:hover {\n      background: rgba(255, 255, 255, 0.1);\n      border-color: var(--stroke-hover);\n      transform: translateY(-2px);\n    }\n\n    \/* Enterprise Section *\/\n    .rentamac-pricing .enterprise-section {\n      margin-top: 8px;\n    }\n\n    .rentamac-pricing .enterprise-card {\n      background: var(--bg);\n      border: 1px solid var(--stroke);\n      border-radius: 24px;\n      padding: 28px;\n      max-width: 520px;\n      margin: 0 auto;\n    }\n\n    .rentamac-pricing .enterprise-card .card-header {\n      text-align: center;\n      margin-bottom: 4px;\n      padding-bottom: 3px;\n      border-bottom: 1px solid var(--stroke);\n    }\n\n    .rentamac-pricing .enterprise-card .card-title {\n      font-size: 24px;\n      font-weight: 700;\n      margin: 0 0 8px;\n      color: var(--text);\n    }\n\n    .rentamac-pricing .enterprise-card .card-subtitle {\n      font-size: 14px;\n      color: var(--text-secondary);\n      margin: 0;\n    }\n\n    .rentamac-pricing .enterprise-benefits {\n      display: flex;\n      gap: 4px;\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .benefit-item {\n      flex: 1;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      gap: 10px;\n      padding: 12px;\n      background: rgba(255, 255, 255, 0.04);\n      border: 1px solid var(--stroke);\n      border-radius: 10px;\n    }\n\n    .rentamac-pricing .benefit-icon {\n      width: 32px;\n      height: 32px;\n      background: rgba(249, 115, 22, 0.15);\n      border-radius: 8px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      color: var(--accent-orange);\n      flex-shrink: 0;\n    }\n\n    .rentamac-pricing .benefit-item h4 {\n      font-size: 13px;\n      font-weight: 600;\n      color: var(--text);\n      margin: 0;\n    }\n\n    \/* Sliders *\/\n    .rentamac-pricing .slider-group {\n      margin-bottom: 4px;\n    }\n\n    .rentamac-pricing .slider-label-row {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      margin-bottom: 3px;\n    }\n\n    .rentamac-pricing .slider-label {\n      font-size: 14px;\n      font-weight: 600;\n      color: var(--text);\n    }\n\n    .rentamac-pricing .slider-value {\n      display: flex;\n      align-items: center;\n      gap: 8px;\n    }\n\n    .rentamac-pricing .slider-value-number {\n      background: rgba(249, 115, 22, 0.12);\n      border: 1px solid rgba(249, 115, 22, 0.25);\n      border-radius: 8px;\n      padding: 4px 12px;\n      font-size: 16px;\n      font-weight: 700;\n      color: var(--accent-orange);\n      min-width: 40px;\n      text-align: center;\n    }\n\n    .rentamac-pricing .slider-discount-badge {\n      background: rgba(249, 115, 22, 0.15);\n      border: 1px solid rgba(249, 115, 22, 0.3);\n      border-radius: 12px;\n      padding: 4px 10px;\n      font-size: 11px;\n      font-weight: 700;\n      color: var(--accent-orange);\n      opacity: 0;\n      transform: scale(0.9);\n      transition: all 0.3s ease;\n    }\n\n    .rentamac-pricing .slider-discount-badge.active {\n      opacity: 1;\n      transform: scale(1);\n    }\n\n    .rentamac-pricing .slider-discount-badge.bounce {\n      animation: rentamacDiscountBounce 0.6s ease;\n    }\n\n    .rentamac-pricing .slider-value-number.bounce {\n      animation: rentamacNumberBounce 0.5s ease;\n    }\n\n    @keyframes rentamacDiscountBounce {\n      0%, 100% { transform: scale(1); }\n      25% { transform: scale(1.2); }\n      50% { transform: scale(0.95); }\n      75% { transform: scale(1.1); }\n    }\n\n    @keyframes rentamacNumberBounce {\n      0%, 100% { transform: scale(1); }\n      30% { transform: scale(1.15); }\n      60% { transform: scale(0.98); }\n    }\n\n    .rentamac-pricing .enterprise-slider {\n      -webkit-appearance: none;\n      appearance: none;\n      width: 100%;\n      height: 6px;\n      border-radius: 10px;\n      background: rgba(255, 255, 255, 0.08);\n      outline: none;\n      cursor: pointer;\n    }\n\n    .rentamac-pricing .enterprise-slider::-webkit-slider-thumb {\n      -webkit-appearance: none;\n      appearance: none;\n      width: 20px;\n      height: 20px;\n      border-radius: 50%;\n      background: var(--accent-orange);\n      cursor: grab;\n      box-shadow: 0 2px 12px rgba(249, 115, 22, 0.4);\n      transition: all 0.2s ease;\n    }\n\n    .rentamac-pricing .enterprise-slider::-webkit-slider-thumb:hover {\n      transform: scale(1.2);\n      box-shadow: 0 4px 16px rgba(249, 115, 22, 0.6);\n    }\n\n    .rentamac-pricing .enterprise-slider::-moz-range-thumb {\n      width: 20px;\n      height: 20px;\n      border-radius: 50%;\n      background: var(--accent-orange);\n      cursor: grab;\n      border: none;\n      box-shadow: 0 2px 12px rgba(249, 115, 22, 0.4);\n    }\n\n    .rentamac-pricing .slider-range-labels {\n      display: flex;\n      justify-content: space-between;\n      margin-top: 8px;\n      font-size: 12px;\n      color: var(--text-muted);\n    }\n\n    \/* Enterprise pricing display *\/\n    .rentamac-pricing .enterprise-pricing {\n      text-align: center;\n      padding: 20px 0;\n      border-top: 1px solid var(--stroke);\n      margin-top: 8px;\n    }\n\n    .rentamac-pricing .non-cumulative-notice {\n      background: rgba(34, 197, 94, 0.08);\n      border: 1px solid rgba(34, 197, 94, 0.2);\n      border-radius: 10px;\n      padding: 10px 16px;\n      margin-bottom: 16px;\n      font-size: 13px;\n      color: var(--accent-green);\n      font-weight: 600;\n      display: none;\n    }\n\n    .rentamac-pricing .enterprise-pricing .price-amount {\n      font-size: 42px;\n      font-weight: 800;\n      color: var(--text);\n      letter-spacing: -1px;\n    }\n\n    .rentamac-pricing .enterprise-pricing .price-label {\n      font-size: 16px;\n      color: var(--text-secondary);\n      margin-left: 4px;\n    }\n\n    .rentamac-pricing .enterprise-pricing .discount-text {\n      font-size: 14px;\n      color: var(--text-muted);\n      margin: 8px 0 4px;\n    }\n\n    .rentamac-pricing .enterprise-pricing .discount-text.active {\n      color: var(--accent-orange);\n      font-weight: 700;\n    }\n\n    .rentamac-pricing .enterprise-pricing .price-breakdown {\n      font-size: 13px;\n      color: var(--text-muted);\n    }\n\n    .rentamac-pricing .enterprise-cta {\n      margin-top: 20px;\n      text-align: center;\n    }\n\n    .rentamac-pricing .enterprise-btn {\n      width: 100%;\n      padding: 16px 24px;\n      font-size: 16px;\n      font-weight: 700;\n      border: none;\n      border-radius: 12px;\n      cursor: pointer;\n      background: linear-gradient(135deg, var(--accent-orange), #ea580c);\n      color: white;\n      transition: all 0.2s ease;\n      box-shadow: 0 8px 24px rgba(249, 115, 22, 0.3);\n    }\n\n    .rentamac-pricing .enterprise-btn:hover {\n      transform: translateY(-2px);\n      box-shadow: 0 12px 32px rgba(249, 115, 22, 0.4);\n    }\n\n    .rentamac-pricing .enterprise-contact {\n      margin-top: 12px;\n      font-size: 14px;\n      color: var(--text-muted);\n    }\n\n    .rentamac-pricing .enterprise-contact a {\n      color: var(--accent-orange);\n      text-decoration: none;\n    }\n\n    .rentamac-pricing .enterprise-contact a:hover {\n      text-decoration: underline;\n    }\n\n    @media (max-width: 500px) {\n      .rentamac-pricing .enterprise-benefits {\n        flex-direction: column;\n      }\n    }\n\n    \/* Google Reviews Section *\/\n    .rentamac-pricing .reviews-section {\n      margin-top: 48px;\n      padding: 20px 0;\n      \/* Break out of container to wider width *\/\n      width: 90vw;\n      max-width: 1000px;\n      position: relative;\n      left: 50%;\n      transform: translateX(-50%);\n    }\n\n    .rentamac-pricing .reviews-header {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      gap: 12px;\n      margin-bottom: 20px;\n    }\n\n    .rentamac-pricing .google-icon-small {\n      width: 24px;\n      height: 24px;\n      flex-shrink: 0;\n    }\n\n    .rentamac-pricing .reviews-header .rating-stars {\n      display: flex;\n      gap: 2px;\n    }\n\n    .rentamac-pricing .reviews-header .rating-stars svg {\n      width: 18px;\n      height: 18px;\n    }\n\n    .rentamac-pricing .reviews-meta {\n      font-size: 15px;\n      color: var(--text-secondary);\n    }\n\n    .rentamac-pricing .reviews-meta .rating-number {\n      font-weight: 700;\n      color: var(--text);\n    }\n\n    .rentamac-pricing .reviews-meta a {\n      color: var(--text-secondary);\n      text-decoration: none;\n    }\n\n    .rentamac-pricing .reviews-meta a:hover {\n      color: var(--text);\n    }\n\n    \/* Reviews Carousel *\/\n    .rentamac-pricing .reviews-carousel-container {\n      position: relative;\n      overflow: hidden;\n      -webkit-mask-image: linear-gradient(to right, transparent 0%, black 10%, black 90%, transparent 100%);\n      mask-image: linear-gradient(to right, transparent 0%, black 10%, black 90%, transparent 100%);\n    }\n\n    .rentamac-pricing .reviews-carousel {\n      display: flex;\n      gap: 20px;\n      animation: rentamacScrollReviews 60s linear infinite;\n      width: max-content;\n    }\n\n    .rentamac-pricing .reviews-carousel:hover {\n      animation-play-state: paused;\n    }\n\n    @keyframes rentamacScrollReviews {\n      0% {\n        transform: translateX(0);\n      }\n      100% {\n        transform: translateX(-50%);\n      }\n    }\n\n    .rentamac-pricing .review-card {\n      flex: 0 0 300px;\n      background: var(--bg);\n      border: 1px solid var(--stroke);\n      border-radius: 16px;\n      padding: 24px;\n      min-height: 180px;\n      display: flex;\n      flex-direction: column;\n    }\n\n    .rentamac-pricing .review-header {\n      display: flex;\n      align-items: center;\n      gap: 12px;\n      margin-bottom: 12px;\n    }\n\n    .rentamac-pricing .reviewer-avatar {\n      width: 40px;\n      height: 40px;\n      border-radius: 50%;\n      background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple));\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      font-size: 16px;\n      font-weight: 700;\n      color: white;\n      flex-shrink: 0;\n    }\n\n    .rentamac-pricing .reviewer-avatar img {\n      width: 100%;\n      height: 100%;\n      border-radius: 50%;\n      object-fit: cover;\n    }\n\n    .rentamac-pricing .reviewer-info {\n      flex: 1;\n      min-width: 0;\n    }\n\n    .rentamac-pricing .reviewer-name {\n      font-size: 14px;\n      font-weight: 600;\n      color: var(--text);\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n    }\n\n    .rentamac-pricing .review-date {\n      font-size: 12px;\n      color: var(--text-muted);\n    }\n\n    .rentamac-pricing .review-stars {\n      display: flex;\n      gap: 2px;\n      margin-bottom: 12px;\n    }\n\n    .rentamac-pricing .review-stars svg {\n      width: 16px;\n      height: 16px;\n      color: #FBBC04;\n    }\n\n    .rentamac-pricing .review-text {\n      font-size: 14px;\n      line-height: 1.6;\n      color: var(--text-secondary);\n      flex: 1;\n      overflow: hidden;\n      display: -webkit-box;\n      -webkit-line-clamp: 5;\n      -webkit-box-orient: vertical;\n    }\n\n    .rentamac-pricing .review-google-icon {\n      margin-top: 12px;\n      opacity: 0.5;\n    }\n\n    .rentamac-pricing .review-google-icon svg {\n      height: 16px;\n      width: auto;\n    }\n\n    @media (max-width: 600px) {\n      .rentamac-pricing .review-card {\n        flex: 0 0 260px;\n      }\n    }\n\n    \/* ============================================\n       Skeleton Loaders\n       Shown while availability + reviews load, then\n       swapped for real cards by the render functions.\n       ============================================ *\/\n    @keyframes rentamacSkeletonShimmer {\n      0%   { background-position: 200% 0; }\n      100% { background-position: -200% 0; }\n    }\n\n    .rentamac-pricing .skeleton-bar {\n      background: linear-gradient(\n        90deg,\n        rgba(255, 255, 255, 0.04) 25%,\n        rgba(255, 255, 255, 0.10) 37%,\n        rgba(255, 255, 255, 0.04) 63%\n      );\n      background-size: 200% 100%;\n      animation: rentamacSkeletonShimmer 1.4s ease-in-out infinite;\n      border-radius: 6px;\n    }\n\n    .rentamac-pricing .cycle-tab.is-skeleton,\n    .rentamac-pricing .storage-option.is-skeleton,\n    .rentamac-pricing .review-card.is-skeleton {\n      cursor: default;\n      pointer-events: none;\n    }\n\n    .rentamac-pricing .cycle-tab.is-skeleton:hover,\n    .rentamac-pricing .storage-option.is-skeleton:hover {\n      background: rgba(255, 255, 255, 0.04);\n      border-color: var(--stroke);\n    }\n\n    \/* Don't auto-scroll the carousel while it's still showing skeletons *\/\n    .rentamac-pricing .reviews-carousel:has(.review-card.is-skeleton) {\n      animation: none;\n    }\n\n    @media (prefers-reduced-motion: reduce) {\n      .rentamac-pricing .skeleton-bar {\n        animation: none;\n      }\n    }\n    .loc-flag{width:18px;height:12px;border-radius:2px;vertical-align:-1px;margin-right:2px;display:inline-block;flex:none}\n  <\/style>\n\n<div class=\"rentamac-pricing\">\n<!-- Availability Dialog -->\n  <div id=\"availabilityOverlay\" class=\"availability-overlay is-hidden\" aria-hidden=\"true\"><\/div>\n  <div id=\"availabilityDialog\" class=\"availability-dialog is-hidden\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"availabilityDialogTitle\">\n    <div class=\"availability-dialog__header\">\n      <h2 id=\"availabilityDialogTitle\" class=\"availability-dialog__title\">All instances are currently allocated<\/h2>\n      <button type=\"button\" id=\"availabilityDialogClose\" class=\"availability-dialog__close\" aria-label=\"Close dialog\">&times;<\/button>\n    <\/div>\n    <p>\n      We&#8217;re at full capacity right now, but we can let you know the moment a Mac becomes available again.\n      Leave your email below and you&#8217;ll be first in line when we spin up new instances.\n    <\/p>\n    <form id=\"availabilityForm\" class=\"availability-form\" novalidate>\n      <label for=\"availabilityEmail\" class=\"sr-only\">Email address<\/label>\n      <input\n        id=\"availabilityEmail\"\n        name=\"email\"\n        type=\"email\"\n        inputmode=\"email\"\n        autocomplete=\"email\"\n        placeholder=\"your@email.com\"\n        aria-label=\"Email address\"\n        required\n      \/>\n      <button type=\"submit\">Notify me<\/button>\n    <\/form>\n    <div id=\"availabilityFeedback\" class=\"availability-feedback info\" role=\"status\"><\/div>\n    <p class=\"availability-disclaimer\">We only use this email to update you about availability. No spam.<\/p>\n  <\/div>\n\n  <div class=\"container\">\n    <header class=\"header\">\n      <h1>Choose Your Plan<\/h1>\n    <\/header>\n\n    <div class=\"pricing-card\">\n      <!-- Device Info -->\n      <div class=\"device-info\">\n        <img decoding=\"async\"\n          src=\"https:\/\/rentamac.io\/wp-content\/uploads\/2025\/09\/mm24-front-cut-1.png\"\n          alt=\"Mac Mini M4\"\n          class=\"device-image\"\n        \/>\n        <div class=\"device-details\">\n          <h2>Dedicated Mac Mini M4<\/h2>\n          <div class=\"device-specs\">\n            <span class=\"spec-badge\">\n              M4 10-core\n              <span class=\"feature-info\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                  <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                  <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                  <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n                <\/svg>\n                <span class=\"tooltip\">Apple M4 chip with 10-core CPU (4 performance cores + 6 efficiency cores) and 10-core GPU. Delivers exceptional single-threaded and multi-threaded performance for development, builds, and creative workloads.<\/span>\n              <\/span>\n            <\/span>\n            <span class=\"spec-badge\">\n              16 GB RAM\n              <span class=\"feature-info\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                  <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                  <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                  <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n                <\/svg>\n                <span class=\"tooltip\">16 GB of unified memory shared between CPU and GPU. Unlike traditional RAM, unified memory eliminates the need to copy data between processors, resulting in faster performance and better efficiency.<\/span>\n              <\/span>\n            <\/span>\n            <span class=\"spec-badge\">\n              256 GB SSD\n              <span class=\"feature-info\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                  <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                  <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                  <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n                <\/svg>\n                <span class=\"tooltip\">256 GB internal NVMe solid-state drive with read speeds up to 3.4 GB\/s. Fast enough for Xcode builds, Docker containers, and large project files. Additional external storage available as add-on.<\/span>\n              <\/span>\n            <\/span>\n            <span class=\"spec-badge\">\n              Tahoe 26.4+\n              <span class=\"feature-info\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                  <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                  <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                  <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n                <\/svg>\n                <span class=\"tooltip\">macOS Tahoe (version 26.4 or later) \u2014 Apple&#8217;s latest operating system. Includes the newest Xcode, Swift, and development tools. Always kept up to date with the latest security patches.<\/span>\n              <\/span>\n            <\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <!-- Location picker. Pre-selected from the visitor's IP (see resolveGeoPreferredLocation);\n           picking a tab pins the choice for the rest of the session.\n           Skeleton baked in for first paint like the cycle tabs below \u2014 rendered from JS only, it\n           appeared a beat after the other two. -->\n      <div class=\"location-section\">\n        <div class=\"section-title\">Location<\/div>\n        <div class=\"cycle-tabs\" id=\"locationTabs\">\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <!-- Billing Cycle -->\n      <div class=\"cycle-section\">\n        <div class=\"section-title\">Billing Cycle<\/div>\n        <!-- Skeleton tabs are baked into the static markup so they show on first paint\n             (no empty flash before JS runs). Replaced by renderCycleTabs() once availability\n             data arrives; renderCycleTabsSkeleton() in init re-renders identical markup. -->\n        <div class=\"cycle-tabs\" id=\"cycleTabs\">\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n          <div class=\"cycle-tab is-skeleton\">\n            <div class=\"skeleton-bar\" style=\"height:14px;width:55%;margin:6px auto 8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:10px;width:40%;margin:0 auto;\"><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <!-- Storage -->\n      <div class=\"storage-section\">\n        <div class=\"section-title\">Storage<\/div>\n        <!-- Skeleton options baked in for first paint (see cycle-tabs note above). -->\n        <div id=\"storageContainer\">\n          <div class=\"storage-options\" id=\"storageOptions\">\n            <div class=\"storage-option is-skeleton\">\n              <div class=\"skeleton-bar\" style=\"height:18px;width:45%;margin:0 auto 8px;\"><\/div>\n              <div class=\"skeleton-bar\" style=\"height:12px;width:70%;margin:0 auto 8px;\"><\/div>\n              <div class=\"skeleton-bar\" style=\"height:13px;width:35%;margin:0 auto;\"><\/div>\n            <\/div>\n            <div class=\"storage-option is-skeleton\">\n              <div class=\"skeleton-bar\" style=\"height:18px;width:45%;margin:0 auto 8px;\"><\/div>\n              <div class=\"skeleton-bar\" style=\"height:12px;width:70%;margin:0 auto 8px;\"><\/div>\n              <div class=\"skeleton-bar\" style=\"height:13px;width:35%;margin:0 auto;\"><\/div>\n            <\/div>\n            <div class=\"storage-option is-skeleton\">\n              <div class=\"skeleton-bar\" style=\"height:18px;width:45%;margin:0 auto 8px;\"><\/div>\n              <div class=\"skeleton-bar\" style=\"height:12px;width:70%;margin:0 auto 8px;\"><\/div>\n              <div class=\"skeleton-bar\" style=\"height:13px;width:35%;margin:0 auto;\"><\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <!-- Features -->\n      <div class=\"features-section\">\n        <div class=\"section-title\">Included<\/div>\n        <div class=\"features-grid\">\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span id=\"accessDuration\">1 month access<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">Continuous 24\/7 access \u2014 not working days or limited hours. Your access starts immediately after payment and auto-renews unless you cancel from the User Portal.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>Remote desktop connection<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">Connect via DeskIn remote desktop software. After purchase, you&#8217;ll receive credentials by email. DeskIn offers the highest frame rate and lowest latency among remote desktop products.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>SSH access<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">Full SSH terminal access to your Mac for remote development, running builds, and file transfers (scp\/sftp). Connect from any terminal using the credentials provided after purchase.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>Admin user access<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">Full administrator privileges (Root access) with no restrictions. Install any software, configure development environments, and have complete control over the system.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>Dedicated Mac<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">The Mac Mini M4 is fully dedicated to you \u2014 no virtual machines or multi-user environment. You get the entire physical machine exclusively for your use.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>Immediate access<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">Instances are already running. You&#8217;ll receive your credentials immediately after payment and can start using your Mac right away \u2014 no waiting time.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>1 Gbps internet<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">High-speed connection from our Cyprus datacenter: up to 1 Gbps download and ~200 Mbps upload. Perfect for large file transfers and CI\/CD workflows.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>Xcode pre-installed<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">Every Mac comes with Xcode already installed and ready to use. Start building and running iOS and macOS apps immediately, with no lengthy download or setup.<\/span>\n            <\/span>\n          <\/div>\n          <div class=\"feature-item\" id=\"sipFeature\" style=\"display: none;\">\n            <span class=\"feature-icon\">&#10003;<\/span>\n            <span>SIP customization<\/span>\n            <span class=\"feature-info\">\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\n                <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"><\/line>\n                <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"><\/line>\n              <\/svg>\n              <span class=\"tooltip\">Since SIP introduces additional hardware risk, we offer customization only on 6-month plans. After purchase, contact support to have it enabled as it requires manual intervention.<\/span>\n            <\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <!-- Price Display -->\n      <div class=\"price-section\">\n        <div class=\"total-label\">Total<\/div>\n        <div class=\"total-price\" id=\"totalPrice\">$99<\/div>\n        <div class=\"price-breakdown\" id=\"priceBreakdown\">$99 billed monthly<\/div>\n        <div class=\"storage-addon-note\" id=\"storageNote\"><\/div>\n      <\/div>\n\n      <!-- CTA -->\n      <button class=\"cta-button\" id=\"ctaButton\">\n        Buy Plan\n      <\/button>\n      <p class=\"checkout-error\" id=\"checkoutError\" role=\"alert\" style=\"display: none;\"><\/p>\n    <\/div>\n\n    <!-- Purchase Information -->\n    <section class=\"purchase-info\">\n      <div class=\"purchase-dropdown\">\n        <button class=\"purchase-dropdown-trigger\" id=\"purchaseDropdownTrigger\" type=\"button\" aria-expanded=\"false\" aria-controls=\"purchaseDropdownContent\">\n          <span>What happens after purchase?<\/span>\n          <svg class=\"purchase-dropdown-icon\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"\/>\n          <\/svg>\n        <\/button>\n        <div class=\"purchase-dropdown-content\" id=\"purchaseDropdownContent\" aria-hidden=\"true\">\n          <p>Once your payment is processed, you will be taken to our User Portal, where you can find your Mac credentials and manage your subscription. An email will also be sent to you with all the necessary information using the email from checkout.<\/p>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- Google Reviews Section -->\n    <section class=\"reviews-section\">\n      <div class=\"reviews-header\">\n        <!-- Google \"G\" Icon -->\n        <svg class=\"google-icon-small\" viewBox=\"0 0 24 24\">\n          <path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\/>\n          <path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\/>\n          <path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\/>\n          <path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\/>\n        <\/svg>\n        <div class=\"rating-stars\" id=\"avgStars\"><\/div>\n        <span class=\"reviews-meta\">\n          <span class=\"rating-number\" id=\"avgRating\">5.0<\/span>\n          <a href=\"https:\/\/maps.app.goo.gl\/v55edKD7K2gePhTh9\" target=\"_blank\" rel=\"noopener nofollow\">on Google<\/a>\n        <\/span>\n      <\/div>\n\n      <div class=\"reviews-carousel-container\">\n        <div class=\"reviews-carousel\" id=\"reviewsCarousel\">\n          <!-- Skeleton placeholders shown until reviews are rendered by JS -->\n          <div class=\"review-card is-skeleton\">\n            <div class=\"review-header\">\n              <div class=\"skeleton-bar\" style=\"width:40px;height:40px;border-radius:50%;flex-shrink:0;\"><\/div>\n              <div class=\"reviewer-info\">\n                <div class=\"skeleton-bar\" style=\"height:14px;width:60%;\"><\/div>\n              <\/div>\n            <\/div>\n            <div class=\"skeleton-bar\" style=\"height:16px;width:96px;margin-bottom:14px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:100%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:92%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:74%;\"><\/div>\n          <\/div>\n          <div class=\"review-card is-skeleton\">\n            <div class=\"review-header\">\n              <div class=\"skeleton-bar\" style=\"width:40px;height:40px;border-radius:50%;flex-shrink:0;\"><\/div>\n              <div class=\"reviewer-info\">\n                <div class=\"skeleton-bar\" style=\"height:14px;width:55%;\"><\/div>\n              <\/div>\n            <\/div>\n            <div class=\"skeleton-bar\" style=\"height:16px;width:96px;margin-bottom:14px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:100%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:88%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:64%;\"><\/div>\n          <\/div>\n          <div class=\"review-card is-skeleton\">\n            <div class=\"review-header\">\n              <div class=\"skeleton-bar\" style=\"width:40px;height:40px;border-radius:50%;flex-shrink:0;\"><\/div>\n              <div class=\"reviewer-info\">\n                <div class=\"skeleton-bar\" style=\"height:14px;width:65%;\"><\/div>\n              <\/div>\n            <\/div>\n            <div class=\"skeleton-bar\" style=\"height:16px;width:96px;margin-bottom:14px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:100%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:90%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:70%;\"><\/div>\n          <\/div>\n          <div class=\"review-card is-skeleton\">\n            <div class=\"review-header\">\n              <div class=\"skeleton-bar\" style=\"width:40px;height:40px;border-radius:50%;flex-shrink:0;\"><\/div>\n              <div class=\"reviewer-info\">\n                <div class=\"skeleton-bar\" style=\"height:14px;width:58%;\"><\/div>\n              <\/div>\n            <\/div>\n            <div class=\"skeleton-bar\" style=\"height:16px;width:96px;margin-bottom:14px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:100%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:85%;margin-bottom:8px;\"><\/div>\n            <div class=\"skeleton-bar\" style=\"height:12px;width:60%;\"><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- Enterprise Section -->\n    <section class=\"enterprise-section\">\n      <div class=\"enterprise-card\">\n        <div class=\"card-header\">\n          <h2 class=\"card-title\">Enterprise<\/h2>\n          <p class=\"card-subtitle\">Mac Mini M4 &#8211; Volume pricing<\/p>\n        <\/div>\n\n        <div class=\"enterprise-benefits\">\n          <div class=\"benefit-item\">\n            <div class=\"benefit-icon\">\n              <svg width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\/>\n              <\/svg>\n            <\/div>\n            <h4>Volume discounts<\/h4>\n          <\/div>\n          <div class=\"benefit-item\">\n            <div class=\"benefit-icon\">\n              <svg width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.031 9-11.622 0-1.042-.133-2.052-.382-3.016z\"\/>\n              <\/svg>\n            <\/div>\n            <h4>SLA guarantees<\/h4>\n          <\/div>\n        <\/div>\n\n        <!-- Quantity Slider -->\n        <div class=\"slider-group\">\n          <div class=\"slider-label-row\">\n            <span class=\"slider-label\">Number of Instances<\/span>\n            <div class=\"slider-value\">\n              <span class=\"slider-value-number\" id=\"quantityValue\">1<\/span>\n              <span class=\"slider-discount-badge\" id=\"quantityDiscountBadge\">10% OFF<\/span>\n            <\/div>\n          <\/div>\n          <input type=\"range\" id=\"quantitySlider\" min=\"1\" max=\"15\" value=\"1\" class=\"enterprise-slider\" \/>\n          <div class=\"slider-range-labels\">\n            <span>1<\/span>\n            <span>15+<\/span>\n          <\/div>\n        <\/div>\n\n        <!-- Duration Slider -->\n        <div class=\"slider-group\">\n          <div class=\"slider-label-row\">\n            <span class=\"slider-label\">Duration (Months)<\/span>\n            <div class=\"slider-value\">\n              <span class=\"slider-value-number\" id=\"durationValue\">1<\/span>\n              <span class=\"slider-discount-badge\" id=\"durationDiscountBadge\">10% OFF<\/span>\n            <\/div>\n          <\/div>\n          <input type=\"range\" id=\"durationSlider\" min=\"1\" max=\"12\" value=\"1\" class=\"enterprise-slider\" \/>\n          <div class=\"slider-range-labels\">\n            <span>1 month<\/span>\n            <span>12 months<\/span>\n          <\/div>\n        <\/div>\n\n        <!-- Pricing Display -->\n        <div class=\"enterprise-pricing\">\n          <div class=\"non-cumulative-notice\" id=\"nonCumulativeNotice\">\n            Discounts are not cumulative\n          <\/div>\n          <div>\n            <span class=\"price-amount\" id=\"enterprisePrice\">$99<\/span>\n            <span class=\"price-label\">total<\/span>\n          <\/div>\n          <p class=\"discount-text\" id=\"discountBadge\">Standard pricing<\/p>\n          <p class=\"price-breakdown\" id=\"priceBreakdownEnterprise\">$99.00\/month per instance<\/p>\n        <\/div>\n\n        <div class=\"enterprise-cta\">\n          <button class=\"enterprise-btn\" onclick=\"if(typeof $crisp !== 'undefined') $crisp.push(['do', 'chat:open']); else window.location.href='mailto:support@rentamac.io';\">\n            Get custom quote\n          <\/button>\n          <p class=\"enterprise-contact\">or email <a href=\"mailto:support@rentamac.io\">support@rentamac.io<\/a><\/p>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- Help Section -->\n    <section class=\"help-section\">\n      <div class=\"help-header\">\n        <h3>Need help deciding?<\/h3>\n        <p class=\"help-subtitle\">See it in action or get your questions answered<\/p>\n      <\/div>\n\n      <div class=\"help-cards\">\n        <div class=\"help-card\">\n          <div class=\"help-icon\">\n            <svg width=\"28\" height=\"28\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n              <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\"\/>\n            <\/svg>\n          <\/div>\n          <h4>Watch live demo<\/h4>\n          <p>See our Mac Mini cloud service in action with a live demonstration. No signup required!<\/p>\n          <button class=\"help-btn secondary\" onclick=\"navigateWithLanguage('\/demo\/');\">\n            <span>View Demo<\/span>\n            <svg width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n              <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 7l5 5m0 0l-5 5m5-5H6\"\/>\n            <\/svg>\n          <\/button>\n        <\/div>\n\n        <div class=\"help-card\">\n          <div class=\"help-icon\">\n            <svg width=\"28\" height=\"28\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n              <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\/>\n            <\/svg>\n          <\/div>\n          <h4>Get answers<\/h4>\n          <p>Find detailed answers to common questions about setup, pricing, and features.<\/p>\n          <button class=\"help-btn secondary\" onclick=\"navigateWithLanguage('\/faq\/');\">\n            <span>Browse FAQ<\/span>\n            <svg width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n              <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 7l5 5m0 0l-5 5m5-5H6\"\/>\n            <\/svg>\n          <\/button>\n        <\/div>\n      <\/div>\n\n      <div class=\"help-footer\">\n        <p class=\"help-footer-text\">Prefer to create your account first?<\/p>\n        <button class=\"help-portal-btn\" onclick=\"window.open('https:\/\/portal.rentamac.io\/register', '_blank');\">\n          <svg width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"\/>\n          <\/svg>\n          <span>Create Account<\/span>\n        <\/button>\n      <\/div>\n    <\/section>\n  <\/div>\n<\/div>\n\n<script>(function(){try{var b=atob(\"CiAgICAoZnVuY3Rpb24oKSB7CiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gUFJJQ0lORyBDT05GSUdVUkFUSU9OIC0gRWRpdCB0aGVzZSB2YWx1ZXMKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgY29uc3QgUFJJQ0lOR19DT05GSUcgPSB7CiAgICAgIGN5Y2xlczogewogICAgICAgIGRhaWx5OiB7CiAgICAgICAgICBuYW1lOiAnRGFpbHknLAogICAgICAgICAgYmFzZVByaWNlOiAxOSwKICAgICAgICAgIGJpbGxpbmdMYWJlbDogJ2JpbGxlZCBkYWlseScsCiAgICAgICAgICBwcmljZVBlckRheTogMTksCiAgICAgICAgICBzdXBwb3J0OiAnU3RhbmRhcmQgc3VwcG9ydCcsCiAgICAgICAgICBhY2Nlc3NEdXJhdGlvbjogJzI0IGhvdXJzIGFjY2VzcycsCiAgICAgICAgICBoYXNTdG9yYWdlOiBmYWxzZSwgLy8gTm8gc3RvcmFnZSBhZGQtb25zIGZvciBkYWlseQogICAgICAgICAgc2F2aW5nczogbnVsbAogICAgICAgIH0sCiAgICAgICAgd2Vla2x5OiB7CiAgICAgICAgICBuYW1lOiAnV2Vla2x5JywKICAgICAgICAgIGJhc2VQcmljZTogNTksCiAgICAgICAgICBiaWxsaW5nTGFiZWw6ICdiaWxsZWQgd2Vla2x5JywKICAgICAgICAgIHByaWNlUGVyRGF5OiA4LjQzLAogICAgICAgICAgc3VwcG9ydDogJ1ByaW9yaXR5IHN1cHBvcnQnLAogICAgICAgICAgYWNjZXNzRHVyYXRpb246ICc3IGRheXMgYWNjZXNzJywKICAgICAgICAgIGhhc1N0b3JhZ2U6IHRydWUsCiAgICAgICAgICBzYXZpbmdzOiBudWxsCiAgICAgICAgfSwKICAgICAgICBtb250aGx5OiB7CiAgICAgICAgICBuYW1lOiAnTW9udGhseScsCiAgICAgICAgICBiYXNlUHJpY2U6IDExOSwKICAgICAgICAgIGJpbGxpbmdMYWJlbDogJ2JpbGxlZCBtb250aGx5JywKICAgICAgICAgIHByaWNlUGVyRGF5OiAzLjk3LAogICAgICAgICAgc3VwcG9ydDogJ1ByaW9yaXR5IHN1cHBvcnQnLAogICAgICAgICAgYWNjZXNzRHVyYXRpb246ICcxIG1vbnRoIGFjY2VzcycsCiAgICAgICAgICBoYXNTdG9yYWdlOiB0cnVlLAogICAgICAgICAgc2F2aW5nczogbnVsbCwKICAgICAgICAgIHBvcHVsYXI6IHRydWUKICAgICAgICB9LAogICAgICAgICczbW9udGgnOiB7CiAgICAgICAgICBuYW1lOiAnMyBNb250aHMnLAogICAgICAgICAgYmFzZVByaWNlOiAzMzksCiAgICAgICAgICBiaWxsaW5nTGFiZWw6ICdiaWxsZWQgZXZlcnkgMyBtb250aHMnLAogICAgICAgICAgcHJpY2VQZXJEYXk6IDMuNzcsCiAgICAgICAgICBzdXBwb3J0OiAnUHJpb3JpdHkgc3VwcG9ydCcsCiAgICAgICAgICBhY2Nlc3NEdXJhdGlvbjogJzMgbW9udGhzIGFjY2VzcycsCiAgICAgICAgICBoYXNTdG9yYWdlOiB0cnVlLAogICAgICAgICAgc2F2aW5nczogJ1NhdmUgNSUnCiAgICAgICAgfSwKICAgICAgICAnNm1vbnRoJzogewogICAgICAgICAgbmFtZTogJzYgTW9udGhzJywKICAgICAgICAgIGJhc2VQcmljZTogNjM5LAogICAgICAgICAgYmlsbGluZ0xhYmVsOiAnYmlsbGVkIGV2ZXJ5IDYgbW9udGhzJywKICAgICAgICAgIHByaWNlUGVyRGF5OiAzLjU1LAogICAgICAgICAgc3VwcG9ydDogJ1ByZW1pdW0gc3VwcG9ydCcsCiAgICAgICAgICBhY2Nlc3NEdXJhdGlvbjogJzYgbW9udGhzIGFjY2VzcycsCiAgICAgICAgICBoYXNTdG9yYWdlOiB0cnVlLAogICAgICAgICAgc2F2aW5nczogJ1NhdmUgMTAlJwogICAgICAgIH0KICAgICAgfSwKCiAgICAgIHN0b3JhZ2U6IHsKICAgICAgICBiYXNlOiB7CiAgICAgICAgICBzaXplOiAyNTYsCiAgICAgICAgICBsYWJlbDogJ0ludGVybmFsIFNTRCcsCiAgICAgICAgICBwcmljZTogMCwKICAgICAgICAgIGlzRGVmYXVsdDogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgYWRkb24yNTY6IHsKICAgICAgICAgIHNpemU6IDUxMiwgLy8gMjU2IGJhc2UgKyAyNTYgYWRkb24KICAgICAgICAgIGxhYmVsOiAnMjU2IEdCICsgMjU2IEdCIGV4dGVybmFsJywKICAgICAgICAgIG1vbnRobHlQcmljZTogOS45MCwgLy8gQmFzZSBtb250aGx5IHByaWNlCiAgICAgICAgICAvLyBNdWx0aXBsaWVycyBmb3IgbG9uZ2VyIHRlcm1zCiAgICAgICAgICAnM21vbnRoTXVsdGlwbGllcic6IDMsCiAgICAgICAgICAnNm1vbnRoTXVsdGlwbGllcic6IDYKICAgICAgICB9LAogICAgICAgIGFkZG9uNTEyOiB7CiAgICAgICAgICBzaXplOiA3NjgsIC8vIDI1NiBiYXNlICsgNTEyIGFkZG9uCiAgICAgICAgICBsYWJlbDogJzI1NiBHQiArIDUxMiBHQiBleHRlcm5hbCcsCiAgICAgICAgICBtb250aGx5UHJpY2U6IDE0LjkwLCAvLyBCYXNlIG1vbnRobHkgcHJpY2UKICAgICAgICAgICczbW9udGhNdWx0aXBsaWVyJzogMywKICAgICAgICAgICc2bW9udGhNdWx0aXBsaWVyJzogNgogICAgICAgIH0KICAgICAgfSwKCiAgICB9OwoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBMT0NBVElPTiBDT05GSUdVUkFUSU9OCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gS2V5IG9yZGVyIGlzIHRoZSBvcmRlciB0aGUgcGlja2VyIHRhYnMgcmVuZGVyIGluIOKAlCB3ZXN0IHRvIGVhc3QsIHNvIEFtZXJpY2Egc2l0cyBpbiB0aGUKICAgIC8vIG1pZGRsZS4gYmFja2VuZEtleSBpcyB0aGUgRGF0YWNlbnRlckxvY2F0aW9uIGVudW0ncyBpbnRlZ2VyIHZhbHVlICh3aGljaCBkb2VzIE5PVCBmb2xsb3cgdGhpcwogICAgLy8gb3JkZXIpLCB1c2VkIGJvdGggZm9yIHRoZSBwZXItREMgYXZhaWxhYmlsaXR5IGNvdW50cyB0aGUgQVBJIHJldHVybnMgYW5kIGZvciB0aGUgZGF0YWNlbnRlcgogICAgLy8gc2VudCB3aGVuIG1pbnRpbmcgYSBjaGVja291dC4KICAgIGNvbnN0IExPQ0FUSU9OUyA9IHsKICAgICAgY3lwcnVzOiB7CiAgICAgICAgZmxhZzogJzxzdmcgY2xhc3M9ImxvYy1mbGFnIiB2aWV3Qm94PSIwIDAgMTkgMTMiIGFyaWEtaGlkZGVuPSJ0cnVlIj48cmVjdCB3aWR0aD0iMTkiIGhlaWdodD0iMTMiIHJ4PSIyIiBmaWxsPSIjMDAzMzk5Ii8+PGcgZmlsbD0iI0ZGQ0MwMCI+PGNpcmNsZSBjeD0iOS41IiBjeT0iMi4zIiByPSIuNjUiLz48Y2lyY2xlIGN4PSIxMS42IiBjeT0iMi44NiIgcj0iLjY1Ii8+PGNpcmNsZSBjeD0iMTMuMTQiIGN5PSI0LjQiIHI9Ii42NSIvPjxjaXJjbGUgY3g9IjEzLjciIGN5PSI2LjUiIHI9Ii42NSIvPjxjaXJjbGUgY3g9IjEzLjE0IiBjeT0iOC42IiByPSIuNjUiLz48Y2lyY2xlIGN4PSIxMS42IiBjeT0iMTAuMTQiIHI9Ii42NSIvPjxjaXJjbGUgY3g9IjkuNSIgY3k9IjEwLjciIHI9Ii42NSIvPjxjaXJjbGUgY3g9IjcuNCIgY3k9IjEwLjE0IiByPSIuNjUiLz48Y2lyY2xlIGN4PSI1Ljg2IiBjeT0iOC42IiByPSIuNjUiLz48Y2lyY2xlIGN4PSI1LjMiIGN5PSI2LjUiIHI9Ii42NSIvPjxjaXJjbGUgY3g9IjUuODYiIGN5PSI0LjQiIHI9Ii42NSIvPjxjaXJjbGUgY3g9IjcuNCIgY3k9IjIuODYiIHI9Ii42NSIvPjwvZz48L3N2Zz4nLAogICAgICAgIGNvbnRpbmVudDogJ0V1cm9wZScsCiAgICAgICAgY291bnRyeTogJ0N5cHJ1cycsCiAgICAgICAgYXZhaWxhYmxlOiB0cnVlLAogICAgICAgIGlzRGVmYXVsdDogdHJ1ZSwKICAgICAgICBiYWNrZW5kS2V5OiAwCiAgICAgIH0sCiAgICAgIHVzYTogewogICAgICAgIGZsYWc6ICc8c3ZnIGNsYXNzPSJsb2MtZmxhZyIgdmlld0JveD0iMCAwIDE5IDEzIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PGRlZnM+PGNsaXBQYXRoIGlkPSJsZnVzIj48cmVjdCB3aWR0aD0iMTkiIGhlaWdodD0iMTMiIHJ4PSIyIi8+PC9jbGlwUGF0aD48L2RlZnM+PGcgY2xpcC1wYXRoPSJ1cmwoI2xmdXMpIj48cmVjdCB3aWR0aD0iMTkiIGhlaWdodD0iMTMiIGZpbGw9IiNCMjIyMzQiLz48ZyBmaWxsPSIjZmZmIj48cmVjdCB5PSIxLjkiIHdpZHRoPSIxOSIgaGVpZ2h0PSIxLjkiLz48cmVjdCB5PSI1LjciIHdpZHRoPSIxOSIgaGVpZ2h0PSIxLjkiLz48cmVjdCB5PSI5LjUiIHdpZHRoPSIxOSIgaGVpZ2h0PSIxLjkiLz48L2c+PHJlY3Qgd2lkdGg9IjguNSIgaGVpZ2h0PSI3IiBmaWxsPSIjM0MzQjZFIi8+PGcgZmlsbD0iI2ZmZiI+PGNpcmNsZSBjeD0iMS44IiBjeT0iMS42IiByPSIuNTUiLz48Y2lyY2xlIGN4PSI0LjIiIGN5PSIxLjYiIHI9Ii41NSIvPjxjaXJjbGUgY3g9IjYuNiIgY3k9IjEuNiIgcj0iLjU1Ii8+PGNpcmNsZSBjeD0iMyIgY3k9IjMuNSIgcj0iLjU1Ii8+PGNpcmNsZSBjeD0iNS40IiBjeT0iMy41IiByPSIuNTUiLz48Y2lyY2xlIGN4PSIxLjgiIGN5PSI1LjQiIHI9Ii41NSIvPjxjaXJjbGUgY3g9IjQuMiIgY3k9IjUuNCIgcj0iLjU1Ii8+PGNpcmNsZSBjeD0iNi42IiBjeT0iNS40IiByPSIuNTUiLz48L2c+PC9nPjwvc3ZnPicsCiAgICAgICAgY29udGluZW50OiAnQW1lcmljYScsCiAgICAgICAgY291bnRyeTogJ1VTQSDCtyBUZXhhcycsCiAgICAgICAgYXZhaWxhYmxlOiB0cnVlLAogICAgICAgIGJhY2tlbmRLZXk6IDIKICAgICAgfSwKICAgICAgaW5kaWE6IHsKICAgICAgICBmbGFnOiAnPHN2ZyBjbGFzcz0ibG9jLWZsYWciIHZpZXdCb3g9IjAgMCAxOSAxMyIgYXJpYS1oaWRkZW49InRydWUiPjxkZWZzPjxjbGlwUGF0aCBpZD0ibGZpbiI+PHJlY3Qgd2lkdGg9IjE5IiBoZWlnaHQ9IjEzIiByeD0iMiIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNsZmluKSI+PHJlY3Qgd2lkdGg9IjE5IiBoZWlnaHQ9IjQuMzMiIGZpbGw9IiNGRjk5MzMiLz48cmVjdCB5PSI0LjMzIiB3aWR0aD0iMTkiIGhlaWdodD0iNC4zMyIgZmlsbD0iI2ZmZiIvPjxyZWN0IHk9IjguNjYiIHdpZHRoPSIxOSIgaGVpZ2h0PSI0LjM0IiBmaWxsPSIjMTM4ODA4Ii8+PGNpcmNsZSBjeD0iOS41IiBjeT0iNi41IiByPSIxLjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDA4OCIgc3Ryb2tlLXdpZHRoPSIuNSIvPjwvZz48L3N2Zz4nLAogICAgICAgIGNvbnRpbmVudDogJ0FzaWEnLAogICAgICAgIGNvdW50cnk6ICdJbmRpYScsCiAgICAgICAgYXZhaWxhYmxlOiB0cnVlLAogICAgICAgIGJhY2tlbmRLZXk6IDEKICAgICAgfQogICAgfTsKCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gQVBJIEVORFBPSU5UUwogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICBjb25zdCBFTkRQT0lOVF9TVEFUVVMgPSAiaHR0cHM6Ly9hcGkucmVudGFtYWMuaW8vYXBpL3dlYnNpdGUvYXZhaWxhYmlsaXR5L3N0YXR1cyIKICAgIGNvbnN0IEVORFBPSU5UX1NVQlNDUklCRSA9ICJodHRwczovL2FwaS5yZW50YW1hYy5pby9hcGkvd2Vic2l0ZS9hdmFpbGFiaWxpdHkvc3Vic2NyaWJlIgogICAgY29uc3QgRU5EUE9JTlRfQURfVFJBQ0tJTkcgPSAiaHR0cHM6Ly9hcGkucmVudGFtYWMuaW8vYXBpL3dlYnNpdGUvYWR0IgogICAgY29uc3QgRU5EUE9JTlRfQ0hFQ0tPVVRfU0VTU0lPTiA9ICJodHRwczovL2FwaS5yZW50YW1hYy5pby9hcGkvY2hlY2tvdXRzL3Nlc3Npb24iCgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIFNUQVRFCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICAgIGxldCBzZWxlY3RlZEN5Y2xlID0gJ21vbnRobHknOwogICAgbGV0IHNlbGVjdGVkU3RvcmFnZSA9ICdiYXNlJzsKICAgIGxldCBzZWxlY3RlZExvY2F0aW9uID0gJ2N5cHJ1cyc7CiAgICBsZXQgdXNlckludGVyYWN0ZWRXaXRoTG9jYXRpb24gPSBmYWxzZTsKICAgIC8vIERlZmF1bHQgYWxsIGF2YWlsYWJpbGl0eSBjb3VudHMgaGlnaCBzbyBldmVyeXRoaW5nIGFwcGVhcnMgYXZhaWxhYmxlIHdoaWxlIHRoZSBBUEkgbG9hZHMuCiAgICAvLyBUaGUgQVBJIHJlc3BvbnNlIGlzIHRoZSBvbmx5IHRoaW5nIHRoYXQgY2FuIG1hcmsgYW4gb3B0aW9uIGFzIHVuYXZhaWxhYmxlLgogICAgbGV0IGN1cnJlbnRBdmFpbGFibGVEZXZpY2VzID0gOTk5OwogICAgbGV0IGF2YWlsYWJsZURldmljZXNXaXRoMjU2R2JEcml2ZSA9IDk5OTsKICAgIGxldCBhdmFpbGFibGVEZXZpY2VzV2l0aDUxMkdiRHJpdmUgPSA5OTk7CiAgICBsZXQgZGFpbHlQbGFuQXZhaWxhYmlsaXR5VGhyZXNob2xkID0gMzsgLy8gVGhyZXNob2xkIGZyb20gQVBJLCBkZWZhdWx0cyB0byAzCiAgICBsZXQgZm9ybVN1Ym1pdHRlZFN1Y2Nlc3NmdWxseSA9IGZhbHNlOwogICAgbGV0IGN1cnJlbnRQcmljaW5nT3B0aW9uID0gbnVsbDsgLy8gVHJhY2tzIHdoaWNoIGF2YWlsYWJpbGl0eSBuZXdzbGV0dGVyIHRvIHN1YnNjcmliZSB0byAoZW51bSB2YWx1ZSkKCiAgICAvLyBBdmFpbGFiaWxpdHlOb3RpZmljYXRpb25UeXBlIGVudW0gdmFsdWVzIChtdXN0IG1hdGNoIGJhY2tlbmQpCiAgICBjb25zdCBBdmFpbGFiaWxpdHlOb3RpZmljYXRpb25UeXBlID0gewogICAgICBEYWlseTogMCwgICAgICAgIC8vIERhaWx5IHBsYW4gLSB0cmlnZ2VycyB3aGVuIGF2YWlsYWJsZURldmljZXMgPiBkYWlseVBsYW5BdmFpbGFiaWxpdHlUaHJlc2hvbGQKICAgICAgQmFzZVN0b3JhZ2U6IDEsICAvLyBCYXNlIDI1NkdCIHN0b3JhZ2UgLSB0cmlnZ2VycyB3aGVuIGFueSBkZXZpY2UgYXZhaWxhYmxlCiAgICAgIEV4dGVybmFsMjU2R2I6IDIsIC8vIDI1NkdCIGV4dGVybmFsIGRyaXZlIC0gdHJpZ2dlcnMgd2hlbiAyNTZHQiBleHRlcm5hbCBhdmFpbGFibGUKICAgICAgRXh0ZXJuYWw1MTJHYjogMyAgLy8gNTEyR0IgZXh0ZXJuYWwgZHJpdmUgLSB0cmlnZ2VycyB3aGVuIDUxMkdCIGV4dGVybmFsIGF2YWlsYWJsZQogICAgfTsKCiAgICAvLyBNaXJyb3JzIHRoZSBiYWNrZW5kIFN1YnNjcmlwdGlvblR5cGUgZW51bS4gVGhlIGF2YWlsYWJpbGl0eS1uZXdzbGV0dGVyIHN1cHBvcnQgbm90aWZpY2F0aW9uCiAgICAvLyByZWNvcmRzIHdoaWNoIGJpbGxpbmcgY3ljbGUgdGhlIHZpc2l0b3Igd2FzIGFmdGVyIChpbmZvcm1hdGlvbmFsIG9ubHkpLgogICAgY29uc3QgU3Vic2NyaXB0aW9uVHlwZSA9IHsKICAgICAgSG91cmx5OiAwLCBEYWlseTogMSwgV2Vla2x5OiAyLCBNb250aGx5OiAzLCBTaXhNb250aHM6IDQsIFllYXJseTogNSwgVGhyZWVNb250aHM6IDYKICAgIH07CgogICAgY29uc3QgQ1lDTEVfVE9fU1VCU0NSSVBUSU9OX1RZUEUgPSB7CiAgICAgIGRhaWx5OiBTdWJzY3JpcHRpb25UeXBlLkRhaWx5LAogICAgICB3ZWVrbHk6IFN1YnNjcmlwdGlvblR5cGUuV2Vla2x5LAogICAgICBtb250aGx5OiBTdWJzY3JpcHRpb25UeXBlLk1vbnRobHksCiAgICAgICczbW9udGgnOiBTdWJzY3JpcHRpb25UeXBlLlRocmVlTW9udGhzLAogICAgICAnNm1vbnRoJzogU3Vic2NyaXB0aW9uVHlwZS5TaXhNb250aHMKICAgIH07CgogICAgLy8gTWlycm9ycyB0aGUgYmFja2VuZCBFeHRlcm5hbERyaXZlT3B0aW9uIGVudW07IG51bGwgbWVhbnMgYSBwbGFpbiBwbGFuIHdpdGggbm8gYWRkLW9uLgogICAgY29uc3QgU1RPUkFHRV9UT19EUklWRV9PUFRJT04gPSB7CiAgICAgIGJhc2U6IG51bGwsCiAgICAgIGFkZG9uMjU2OiAwLAogICAgICBhZGRvbjUxMjogMQogICAgfTsKCiAgICBjb25zdCBTVE9SQUdFX1RPX05PVElGSUNBVElPTl9UWVBFID0gewogICAgICBiYXNlOiBBdmFpbGFiaWxpdHlOb3RpZmljYXRpb25UeXBlLkJhc2VTdG9yYWdlLAogICAgICBhZGRvbjI1NjogQXZhaWxhYmlsaXR5Tm90aWZpY2F0aW9uVHlwZS5FeHRlcm5hbDI1NkdiLAogICAgICBhZGRvbjUxMjogQXZhaWxhYmlsaXR5Tm90aWZpY2F0aW9uVHlwZS5FeHRlcm5hbDUxMkdiCiAgICB9OwoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBET00gRUxFTUVOVFMgKGxhenktbG9hZGVkKQogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICBsZXQgYXZhaWxhYmlsaXR5RGlhbG9nLCBhdmFpbGFiaWxpdHlPdmVybGF5LCBhdmFpbGFiaWxpdHlEaWFsb2dDbG9zZSwgCiAgICAgICAgYXZhaWxhYmlsaXR5Rm9ybSwgYXZhaWxhYmlsaXR5RmVlZGJhY2ssIGF2YWlsYWJpbGl0eUVtYWlsOwoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBUUkFDS0lORyBGVU5DVElPTlMKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgZnVuY3Rpb24gZ2VuZXJhdGVHdWlkKCkgewogICAgICByZXR1cm4gJ3h4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eCcucmVwbGFjZSgvW3h5XS9nLCBmdW5jdGlvbihjKSB7CiAgICAgICAgY29uc3QgciA9IE1hdGgucmFuZG9tKCkgKiAxNiB8IDA7CiAgICAgICAgY29uc3QgdiA9IGMgPT09ICd4JyA\/IHIgOiAociAmIDB4MyB8IDB4OCk7CiAgICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpOwogICAgICB9KTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRBZHRQYXlsb2FkKCkgewogICAgICB0cnkgewogICAgICAgIGNvbnN0IHBheWxvYWRTdHIgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYWR0UGF5bG9hZCcpOwogICAgICAgIGlmIChwYXlsb2FkU3RyKSB7CiAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShwYXlsb2FkU3RyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gZ2V0IGFkdFBheWxvYWQnLCBlKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIGFzeW5jIGZ1bmN0aW9uIGVuc3VyZUFkdFBheWxvYWQoKSB7CiAgICAgIGxldCBwYXlsb2FkID0gZ2V0QWR0UGF5bG9hZCgpOwoKICAgICAgaWYgKCFwYXlsb2FkKSB7CiAgICAgICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTsKICAgICAgICBjb25zdCBnY2xpZCA9IHVybFBhcmFtcy5nZXQoJ2djbGlkJykgfHwgbnVsbDsKICAgICAgICBjb25zdCBtc2Nsa2lkID0gdXJsUGFyYW1zLmdldCgnbXNjbGtpZCcpIHx8IG51bGw7CgogICAgICAgIHBheWxvYWQgPSB7CiAgICAgICAgICBDbGllbnRSZWZlcmVuY2VJZDogZ2VuZXJhdGVHdWlkKCksCiAgICAgICAgICBHY2xpZDogZ2NsaWQsCiAgICAgICAgICBNc0Nsa2lkOiBtc2Nsa2lkLAogICAgICAgICAgTGFuZGluZ1BhZ2VVcmw6IHdpbmRvdy5sb2NhdGlvbi5ocmVmCiAgICAgICAgfTsKCiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FkdFBheWxvYWQnLCBKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7CiAgICAgICAgY29uc29sZS5sb2coJ0NyZWF0ZWQgYWR0UGF5bG9hZCBpbiBsb2NhbFN0b3JhZ2U6JywgcGF5bG9hZCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICBmZXRjaChFTkRQT0lOVF9BRF9UUkFDS0lORywgewogICAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sCiAgICAgICAgICAgIC8vIFNlbmQgY3JlZGVudGlhbHMgc28gdGhlIHNlcnZlci1zZXQgZmlyc3QtcGFydHkgcmFtX3ZpZCBjb29raWUgKGtleWVkIHRvIHRoaXMgc2FtZQogICAgICAgICAgICAvLyBDbGllbnRSZWZlcmVuY2VJZCkgaXMgc3RvcmVkIOKAlCBpdCBsZXRzIHRoZSBwb3J0YWwgYnJpZGdlIHJlc29sdmUgdGhpcyByb3cgYWZ0ZXIgbG9naW4uCiAgICAgICAgICAgIGNyZWRlbnRpYWxzOiAnaW5jbHVkZScsCiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpCiAgICAgICAgICB9KS5jYXRjaChlcnIgPT4gewogICAgICAgICAgICBjb25zb2xlLmVycm9yKCdBRFQgQVBJIGNhbGwgZmFpbGVkOicsIGVycik7CiAgICAgICAgICB9KTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gc2VuZCBBRFQgcmVxdWVzdDonLCBlKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHJldHVybiBwYXlsb2FkOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE1ldGFUcmFja2luZ1BhcmFtcygpIHsKICAgICAgdHJ5IHsKICAgICAgICBjb25zdCBjb29raWVzID0gZG9jdW1lbnQuY29va2llLnNwbGl0KCc7Jyk7CiAgICAgICAgbGV0IGZicCA9IG51bGw7CiAgICAgICAgbGV0IGZiYyA9IG51bGw7CgogICAgICAgIGZvciAobGV0IGNvb2tpZSBvZiBjb29raWVzKSB7CiAgICAgICAgICBjb25zdCBbbmFtZSwgdmFsdWVdID0gY29va2llLnRyaW0oKS5zcGxpdCgnPScpOwogICAgICAgICAgaWYgKG5hbWUgPT09ICdfZmJwJykgZmJwID0gdmFsdWU7CiAgICAgICAgICBpZiAobmFtZSA9PT0gJ19mYmMnKSBmYmMgPSB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB7IGZicCwgZmJjIH07CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gZ2V0IE1ldGEgdHJhY2tpbmcgcGFyYW1zOicsIGUpOwogICAgICAgIHJldHVybiB7IGZicDogbnVsbCwgZmJjOiBudWxsIH07CiAgICAgIH0KICAgIH0KCiAgICBhc3luYyBmdW5jdGlvbiB0cmFja0FkQ29udmVyc2lvbihjbGllbnRSZWZlcmVuY2VJZCwgcGxhblR5cGUpIHsKICAgICAgdHJ5IHsKICAgICAgICBjb25zdCBhZHRQYXlsb2FkID0gZ2V0QWR0UGF5bG9hZCgpOwogICAgICAgIGNvbnN0IG1ldGFQYXJhbXMgPSBnZXRNZXRhVHJhY2tpbmdQYXJhbXMoKTsKICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpOwogICAgICAgIGNvbnN0IG1ldGFDbGlja0lkID0gdXJsUGFyYW1zLmdldCgnZmJjbGlkJykgfHwgbnVsbDsKCiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHsKICAgICAgICAgIGNsaWVudFJlZmVyZW5jZUlkOiBjbGllbnRSZWZlcmVuY2VJZCwKICAgICAgICAgIEdjbGlkOiBhZHRQYXlsb2FkPy5HY2xpZCB8fCBudWxsLAogICAgICAgICAgTXNDbGtpZDogYWR0UGF5bG9hZD8uTXNDbGtpZCB8fCBudWxsLAogICAgICAgICAgTGFuZGluZ1BhZ2VVcmw6IGFkdFBheWxvYWQ\/LkxhbmRpbmdQYWdlVXJsIHx8IG51bGwsCiAgICAgICAgICBPcmlnaW5hbENsaWVudFJlZmVyZW5jZUlkOiBhZHRQYXlsb2FkPy5DbGllbnRSZWZlcmVuY2VJZCB8fCBudWxsLAogICAgICAgICAgbWV0YUNsaWNrSWQ6IG1ldGFDbGlja0lkLAogICAgICAgICAgbWV0YUZicDogbWV0YVBhcmFtcy5mYnAsCiAgICAgICAgICBtZXRhRmJjOiBtZXRhUGFyYW1zLmZiYywKICAgICAgICAgIHBsYW5UeXBlOiBwbGFuVHlwZQogICAgICAgIH07CgogICAgICAgIGZldGNoKEVORFBPSU5UX0FEX1RSQUNLSU5HLCB7CiAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LAogICAgICAgICAgY3JlZGVudGlhbHM6ICdpbmNsdWRlJywKICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpCiAgICAgICAgfSkuY2F0Y2goZXJyID0+IHsKICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FkIHRyYWNraW5nIGZhaWxlZDonLCBlcnIpOwogICAgICAgIH0pOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgY29uc29sZS5lcnJvcignQWQgdHJhY2tpbmcgZXJyb3I6JywgZSk7CiAgICAgIH0KICAgIH0KCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gQVZBSUxBQklMSVRZIEZVTkNUSU9OUwogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAvLyBNb3N0IHJlY2VudCBhdmFpbGFiaWxpdHkgcGF5bG9hZCBmcm9tIHRoZSBBUEksIGtlcHQgc28gd2UgY2FuIHJlLWRlcml2ZSB0aGUKICAgIC8vIHNlbGVjdGVkIGRhdGFjZW50ZXIncyBjb3VudHMgd2hlbiB0aGUgdXNlciBzd2l0Y2hlcyBsb2NhdGlvbiB3aXRob3V0IHJlLWZldGNoaW5nLgogICAgbGV0IGxhc3RBdmFpbGFiaWxpdHlQYXlsb2FkID0gbnVsbDsKCiAgICAvLyBGbGlwcyB0cnVlIG9uY2UgdGhlIHN0YXR1cyBBUEkgaGFzIGFuc3dlcmVkIChlaXRoZXIgd2F5KSBvciB0aGUgc2FmZXR5IHRpbWVvdXQgZmlyZWQuIEdhdGVzIHRoZQogICAgLy8gc2tlbGV0b24gc3dhcDogYSBnZW8tZHJpdmVuIGxvY2F0aW9uIGNoYW5nZSBjYW4gbGFuZCBmaXJzdCwgYW5kIGl0cyBvcHRpbWlzdGljCiAgICAvLyBldmVyeXRoaW5nLWF2YWlsYWJsZSBkZWZhdWx0cyBtdXN0IG5vdCBwYWludCBjYXJkcyB0aGF0IHRoZW4gZmxpcCB0byBzb2xkIG91dC4KICAgIGxldCBhdmFpbGFiaWxpdHlTdGF0dXNTZXR0bGVkID0gZmFsc2U7CgogICAgLy8gUHVsbCB0aGUgY291bnRzIGZvciB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGRhdGFjZW50ZXIgb3V0IG9mIHRoZSBwYXlsb2FkIGFuZAogICAgLy8gdXBkYXRlIHRoZSBnbG9iYWwgYXZhaWxhYmlsaXR5IHN0YXRlLiBGYWxscyBiYWNrIHRvICJldmVyeXRoaW5nIGF2YWlsYWJsZSIgd2hlbgogICAgLy8gdGhlIHBheWxvYWQgZG9lc24ndCBpbmNsdWRlIHRoZSBzZWxlY3RlZCBEQyAoZS5nLiBiZWZvcmUgdGhlIEFQSSBjYWxsIGhhcyBjb21lIGJhY2spLgogICAgZnVuY3Rpb24gYXBwbHlBdmFpbGFiaWxpdHlGb3JTZWxlY3RlZExvY2F0aW9uKCkgewogICAgICBjb25zdCBiYWNrZW5kS2V5ID0gTE9DQVRJT05TW3NlbGVjdGVkTG9jYXRpb25dPy5iYWNrZW5kS2V5OwogICAgICBjb25zdCBkYyA9IGxhc3RBdmFpbGFiaWxpdHlQYXlsb2FkPy5kYXRhY2VudGVycz8uZmluZChkID0+IGQubG9jYXRpb24gPT09IGJhY2tlbmRLZXkpOwoKICAgICAgLy8gRXZlcnkgY291bnQgKGJhc2UgZGV2aWNlcyBBTkQgZHJpdmUtZXF1aXBwZWQgZGV2aWNlcykgaXMgcmVhZCBmcm9tIHRoZSBTRUxFQ1RFRCBkYXRhY2VudGVyLgogICAgICAvLyBBZGQtb25zIGFyZSBuZXZlciBzb3VyY2VkIGZyb20gYW5vdGhlciBEQzogd2hhdCB0aGUgdmlzaXRvciBzZWVzIHVuZGVyIGEgbG9jYXRpb24gdGFiIGlzCiAgICAgIC8vIGV4YWN0bHkgd2hhdCB0aGF0IGxvY2F0aW9uIGNhbiBmdWxmaWwsIGFuZCBjaGVja291dCBhbHdheXMgZ29lcyB0byB0aGUgc2VsZWN0ZWQgREMuCiAgICAgIGlmIChkYykgewogICAgICAgIGN1cnJlbnRBdmFpbGFibGVEZXZpY2VzID0gTnVtYmVyKGRjLmF2YWlsYWJsZURldmljZXMgPz8gMCk7CiAgICAgICAgYXZhaWxhYmxlRGV2aWNlc1dpdGgyNTZHYkRyaXZlID0gTnVtYmVyKGRjLmF2YWlsYWJsZURldmljZXNXaXRoMjU2R2JEcml2ZSA\/PyAwKTsKICAgICAgICBhdmFpbGFibGVEZXZpY2VzV2l0aDUxMkdiRHJpdmUgPSBOdW1iZXIoZGMuYXZhaWxhYmxlRGV2aWNlc1dpdGg1MTJHYkRyaXZlID8\/IDApOwogICAgICAgIGRhaWx5UGxhbkF2YWlsYWJpbGl0eVRocmVzaG9sZCA9IE51bWJlcihkYy5kYWlseVBsYW5BdmFpbGFiaWxpdHlUaHJlc2hvbGQgPz8gMyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gTm8gZGF0YSBmb3IgdGhpcyBEQyB5ZXQ6IGtlZXAgZGVmYXVsdHMgc28gbm90aGluZyBhcHBlYXJzIGFydGlmaWNpYWxseSBvdXQgb2Ygc3RvY2suCiAgICAgICAgY3VycmVudEF2YWlsYWJsZURldmljZXMgPSA5OTk7CiAgICAgICAgYXZhaWxhYmxlRGV2aWNlc1dpdGgyNTZHYkRyaXZlID0gOTk5OwogICAgICAgIGF2YWlsYWJsZURldmljZXNXaXRoNTEyR2JEcml2ZSA9IDk5OTsKICAgICAgICBkYWlseVBsYW5BdmFpbGFiaWxpdHlUaHJlc2hvbGQgPSAzOwogICAgICB9CgoKICAgICAgaWYgKCFhdmFpbGFiaWxpdHlTdGF0dXNTZXR0bGVkKSByZXR1cm47CgogICAgICByZW5kZXJDeWNsZVRhYnMoKTsKICAgICAgcmVuZGVyU3RvcmFnZU9wdGlvbnMoKTsKICAgICAgdXBkYXRlUHJpY2VEaXNwbGF5KCk7CiAgICAgIHVwZGF0ZUN0YUJ1dHRvblN0YXRlKCk7CiAgICAgIHJlbmRlckF2YWlsYWJpbGl0eU5vdGljZXMoKTsKICAgIH0KCiAgICBhc3luYyBmdW5jdGlvbiBmZXRjaEF2YWlsYWJpbGl0eVN0YXR1cygpIHsKICAgICAgdHJ5IHsKICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKEVORFBPSU5UX1NUQVRVUywgeyBtZXRob2Q6ICJHRVQiIH0pOwogICAgICAgIGlmICghcmVzcG9uc2Uub2spIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3RhdHVzIEFQSSByZXNwb25kZWQgd2l0aCAke3Jlc3BvbnNlLnN0YXR1c31gKTsKICAgICAgICB9CgogICAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7CiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHBheWxvYWQ\/LmRhdGFjZW50ZXJzKSkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJTdGF0dXMgQVBJIHJldHVybmVkIGFuIGludmFsaWQgcGF5bG9hZCIpOwogICAgICAgIH0KCiAgICAgICAgbGFzdEF2YWlsYWJpbGl0eVBheWxvYWQgPSBwYXlsb2FkOwogICAgICAgIGF2YWlsYWJpbGl0eVN0YXR1c1NldHRsZWQgPSB0cnVlOwogICAgICAgIGFwcGx5QXZhaWxhYmlsaXR5Rm9yU2VsZWN0ZWRMb2NhdGlvbigpOwogICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgIGNvbnNvbGUuZXJyb3IoIkZhaWxlZCB0byBmZXRjaCBhdmFpbGFiaWxpdHkgc3RhdHVzIiwgZXJyb3IpOwogICAgICAgIC8vIE9uIGVycm9yLCBrZWVwIGV2ZXJ5dGhpbmcgYXZhaWxhYmxlIC0gdGhlIEFQSSBuZXZlciBleHBsaWNpdGx5IHNhaWQgYW55dGhpbmcgd2FzIHVuYXZhaWxhYmxlLgogICAgICAgIGxhc3RBdmFpbGFiaWxpdHlQYXlsb2FkID0gbnVsbDsKICAgICAgICBhdmFpbGFiaWxpdHlTdGF0dXNTZXR0bGVkID0gdHJ1ZTsKICAgICAgICBhcHBseUF2YWlsYWJpbGl0eUZvclNlbGVjdGVkTG9jYXRpb24oKTsKICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHVwZGF0ZUN0YUJ1dHRvblN0YXRlKCkgewogICAgICBjb25zdCBjdGFCdXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY3RhQnV0dG9uJyk7CgogICAgICAvLyBDaGVjayBhdmFpbGFiaWxpdHkgYmFzZWQgb24gc2VsZWN0ZWQgc3RvcmFnZSBvcHRpb24KICAgICAgbGV0IGlzU2VsZWN0ZWRTdG9yYWdlT3V0T2ZTdG9jayA9IGZhbHNlOwogICAgICBpZiAoc2VsZWN0ZWRTdG9yYWdlID09PSAnYmFzZScpIHsKICAgICAgICBpc1NlbGVjdGVkU3RvcmFnZU91dE9mU3RvY2sgPSBjdXJyZW50QXZhaWxhYmxlRGV2aWNlcyA9PT0gMDsKICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZFN0b3JhZ2UgPT09ICdhZGRvbjI1NicpIHsKICAgICAgICBpc1NlbGVjdGVkU3RvcmFnZU91dE9mU3RvY2sgPSBhdmFpbGFibGVEZXZpY2VzV2l0aDI1NkdiRHJpdmUgPT09IDA7CiAgICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRTdG9yYWdlID09PSAnYWRkb241MTInKSB7CiAgICAgICAgaXNTZWxlY3RlZFN0b3JhZ2VPdXRPZlN0b2NrID0gYXZhaWxhYmxlRGV2aWNlc1dpdGg1MTJHYkRyaXZlID09PSAwOwogICAgICB9CgogICAgICAvLyBDaGVjayBpZiBkYWlseSBwbGFuIGlzIHNlbGVjdGVkIGJ1dCBub3QgZW5vdWdoIGRldmljZXMgYXZhaWxhYmxlCiAgICAgIGNvbnN0IGlzRGFpbHlQbGFuVW5hdmFpbGFibGUgPSBzZWxlY3RlZEN5Y2xlID09PSAnZGFpbHknICYmIGdldFRvdGFsQXZhaWxhYmxlRGV2aWNlcygpIDw9IGRhaWx5UGxhbkF2YWlsYWJpbGl0eVRocmVzaG9sZDsKCiAgICAgIGlmIChpc1NlbGVjdGVkU3RvcmFnZU91dE9mU3RvY2sgfHwgaXNEYWlseVBsYW5VbmF2YWlsYWJsZSkgewogICAgICAgIGN0YUJ1dHRvbi50ZXh0Q29udGVudCA9ICdKb2luIFdhaXRsaXN0JzsKICAgICAgICBjdGFCdXR0b24uY2xhc3NMaXN0LmFkZCgnb3V0LW9mLXN0b2NrJyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY3RhQnV0dG9uLnRleHRDb250ZW50ID0gJ0J1eSBQbGFuJzsKICAgICAgICBjdGFCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnb3V0LW9mLXN0b2NrJyk7CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBvcGVuQXZhaWxhYmlsaXR5RGlhbG9nKHByaWNpbmdPcHRpb24pIHsKICAgICAgY3VycmVudFByaWNpbmdPcHRpb24gPSBwcmljaW5nT3B0aW9uICE9PSB1bmRlZmluZWQgPyBwcmljaW5nT3B0aW9uIDogbnVsbDsKCiAgICAgIC8vIFVwZGF0ZSBkaWFsb2cgY29udGVudCBiYXNlZCBvbiB0aGUgcmVhc29uLiBDb3B5IG5hbWVzIHRoZSBzZWxlY3RlZCByZWdpb24gb25jZSB0aGUKICAgICAgLy8gc3RhdHVzIHBheWxvYWQgaXMgaW4sIGFuZCB0aGUgIlByZWZlciBub3QgdG8gd2FpdD8iIHJvdyBvZmZlcnMgYW55IHJlZ2lvbiB0aGF0IGhhcyBpdC4KICAgICAgY29uc3QgdGl0bGVFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdmFpbGFiaWxpdHlEaWFsb2dUaXRsZScpOwogICAgICBjb25zdCBkZXNjRWwgPSBhdmFpbGFiaWxpdHlEaWFsb2cucXVlcnlTZWxlY3RvcigncCcpOwogICAgICBjb25zdCByZWFkeSA9IG5vdGljZXNSZWFkeSgpOwogICAgICBjb25zdCBoZXJlID0gc2VsZWN0ZWRMb2NhdGlvbk5hbWUoKTsKICAgICAgY29uc3QgaW5IZXJlID0gcmVhZHkgPyBgIGluICR7aGVyZX1gIDogJyc7CiAgICAgIGNvbnN0IGlzRXh0ZXJuYWxEcml2ZU9wdGlvbiA9IHByaWNpbmdPcHRpb24gPT09IEF2YWlsYWJpbGl0eU5vdGlmaWNhdGlvblR5cGUuRXh0ZXJuYWwyNTZHYgogICAgICAgIHx8IHByaWNpbmdPcHRpb24gPT09IEF2YWlsYWJpbGl0eU5vdGlmaWNhdGlvblR5cGUuRXh0ZXJuYWw1MTJHYjsKICAgICAgY29uc3QgcmVnaW9uU29sZE91dCA9IHJlYWR5ICYmICFsb2NhdGlvbkhhcyhzZWxlY3RlZExvY2F0aW9uLCAnYW55Jyk7CgogICAgICBpZiAocHJpY2luZ09wdGlvbiA9PT0gQXZhaWxhYmlsaXR5Tm90aWZpY2F0aW9uVHlwZS5EYWlseSkgewogICAgICAgIHRpdGxlRWwudGV4dENvbnRlbnQgPSAnRGFpbHkgcGxhbiB0ZW1wb3JhcmlseSB1bmF2YWlsYWJsZSc7CiAgICAgICAgZGVzY0VsLnRleHRDb250ZW50ID0gYFRoZSBkYWlseSBwbGFuIGlzIGN1cnJlbnRseSB1bmF2YWlsYWJsZSR7aW5IZXJlfSBkdWUgdG8gaGlnaCBkZW1hbmQuYAogICAgICAgICAgKyAocmVnaW9uU29sZE91dCA\/ICcnIDogJyBXZWVrbHksIG1vbnRobHksIGFuZCBsb25nZXIgcGxhbnMgYXJlIHN0aWxsIGF2YWlsYWJsZS4nKQogICAgICAgICAgKyAnIExlYXZlIHlvdXIgZW1haWwgYmVsb3cgYW5kIHdlXHUyMDE5bGwgbm90aWZ5IHlvdSBhcyBzb29uIGFzIHRoZSBkYWlseSBwbGFuIGlzIGJhY2suJzsKICAgICAgICByZW5kZXJEaWFsb2dBbHRlcm5hdGl2ZSgnZGFpbHknLCAnZGFpbHknKTsKICAgICAgfSBlbHNlIGlmIChpc0V4dGVybmFsRHJpdmVPcHRpb24gJiYgcmVhZHkgJiYgIXJlZ2lvblNvbGRPdXQpIHsKICAgICAgICAvLyBPbmx5IHRoaXMgZHJpdmUgY29uZmlndXJhdGlvbiBpcyBnb25lOyBiYXNlIE1hY3MgYXJlIHN0aWxsIG9uIG9mZmVyIGhlcmUuCiAgICAgICAgdGl0bGVFbC50ZXh0Q29udGVudCA9ICdUaGlzIHN0b3JhZ2Ugb3B0aW9uIGlzIGN1cnJlbnRseSB1bmF2YWlsYWJsZSc7CiAgICAgICAgZGVzY0VsLnRleHRDb250ZW50ID0gYEV2ZXJ5IE1hYyB3aXRoIHRoaXMgZHJpdmUgY29uZmlndXJhdGlvbiR7aW5IZXJlfSBpcyBhbGxvY2F0ZWQgcmlnaHQgbm93LiBMZWF2ZSB5b3VyIGVtYWlsIGJlbG93IGFuZCB3ZVx1MjAxOWxsIGxldCB5b3Uga25vdyB0aGUgbW9tZW50IG9uZSBmcmVlcyB1cC5gOwogICAgICAgIHJlbmRlckRpYWxvZ0FsdGVybmF0aXZlKHByaWNpbmdPcHRpb24gPT09IEF2YWlsYWJpbGl0eU5vdGlmaWNhdGlvblR5cGUuRXh0ZXJuYWwyNTZHYiA\/ICdhZGRvbjI1NicgOiAnYWRkb241MTInLCBudWxsKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aXRsZUVsLnRleHRDb250ZW50ID0gcmVhZHkgPyBgQWxsIGluc3RhbmNlcyBpbiAke2hlcmV9IGFyZSBjdXJyZW50bHkgYWxsb2NhdGVkYCA6ICdBbGwgaW5zdGFuY2VzIGFyZSBjdXJyZW50bHkgYWxsb2NhdGVkJzsKICAgICAgICBkZXNjRWwudGV4dENvbnRlbnQgPSBgV2VcdTIwMTlyZSBhdCBmdWxsIGNhcGFjaXR5JHtpbkhlcmV9IHJpZ2h0IG5vdywgYnV0IHdlIGNhbiBsZXQgeW91IGtub3cgdGhlIG1vbWVudCBhIE1hYyBiZWNvbWVzIGF2YWlsYWJsZSBhZ2Fpbi4gTGVhdmUgeW91ciBlbWFpbCBiZWxvdyBhbmQgeW91XHUyMDE5bGwgYmUgZmlyc3QgaW4gbGluZSB3aGVuIHdlIHNwaW4gdXAgbmV3IGluc3RhbmNlcy5gOwogICAgICAgIHJlbmRlckRpYWxvZ0FsdGVybmF0aXZlKCdhbnknLCBudWxsKTsKICAgICAgfQoKICAgICAgYXZhaWxhYmlsaXR5RGlhbG9nLmNsYXNzTGlzdC5yZW1vdmUoImlzLWhpZGRlbiIpOwogICAgICBhdmFpbGFiaWxpdHlPdmVybGF5LmNsYXNzTGlzdC5yZW1vdmUoImlzLWhpZGRlbiIpOwogICAgICBhdmFpbGFiaWxpdHlPdmVybGF5LnNldEF0dHJpYnV0ZSgiYXJpYS1oaWRkZW4iLCAiZmFsc2UiKTsKICAgICAgYXZhaWxhYmlsaXR5RW1haWwuZm9jdXMoeyBwcmV2ZW50U2Nyb2xsOiB0cnVlIH0pOwogICAgfQoKICAgIGZ1bmN0aW9uIGNsb3NlQXZhaWxhYmlsaXR5RGlhbG9nKCkgewogICAgICBhdmFpbGFiaWxpdHlEaWFsb2cuY2xhc3NMaXN0LmFkZCgiaXMtaGlkZGVuIik7CiAgICAgIGF2YWlsYWJpbGl0eU92ZXJsYXkuY2xhc3NMaXN0LmFkZCgiaXMtaGlkZGVuIik7CiAgICAgIGF2YWlsYWJpbGl0eU92ZXJsYXkuc2V0QXR0cmlidXRlKCJhcmlhLWhpZGRlbiIsICJ0cnVlIik7CgogICAgICBpZiAoZm9ybVN1Ym1pdHRlZFN1Y2Nlc3NmdWxseSkgewogICAgICAgIGZvcm1TdWJtaXR0ZWRTdWNjZXNzZnVsbHkgPSBmYWxzZTsKICAgICAgICBjb25zdCBzdWJtaXRCdXR0b24gPSBhdmFpbGFiaWxpdHlGb3JtLnF1ZXJ5U2VsZWN0b3IoImJ1dHRvbiIpOwogICAgICAgIHN1Ym1pdEJ1dHRvbi50ZXh0Q29udGVudCA9ICJOb3RpZnkgbWUiOwogICAgICAgIHN1Ym1pdEJ1dHRvbi5zdHlsZS5iYWNrZ3JvdW5kID0gIiI7CiAgICAgICAgc3VibWl0QnV0dG9uLnN0eWxlLmNvbG9yID0gIiI7CiAgICAgICAgYXZhaWxhYmlsaXR5RmVlZGJhY2sudGV4dENvbnRlbnQgPSAiIjsKICAgICAgICBhdmFpbGFiaWxpdHlGZWVkYmFjay5jbGFzc05hbWUgPSAiYXZhaWxhYmlsaXR5LWZlZWRiYWNrIGluZm8iOwogICAgICB9CiAgICAgIGN1cnJlbnRQcmljaW5nT3B0aW9uID0gbnVsbDsKICAgIH0KCiAgICBhc3luYyBmdW5jdGlvbiBzdWJtaXRBdmFpbGFiaWxpdHlGb3JtKGV2ZW50KSB7CiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CgogICAgICBpZiAoZm9ybVN1Ym1pdHRlZFN1Y2Nlc3NmdWxseSkgewogICAgICAgIGNsb3NlQXZhaWxhYmlsaXR5RGlhbG9nKCk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBjb25zdCBlbWFpbCA9IGF2YWlsYWJpbGl0eUVtYWlsLnZhbHVlLnRyaW0oKTsKICAgICAgaWYgKCFlbWFpbCkgewogICAgICAgIGF2YWlsYWJpbGl0eUZlZWRiYWNrLnRleHRDb250ZW50ID0gIlBsZWFzZSBlbnRlciBhIHZhbGlkIGVtYWlsIGFkZHJlc3MuIjsKICAgICAgICBhdmFpbGFiaWxpdHlGZWVkYmFjay5jbGFzc05hbWUgPSAiYXZhaWxhYmlsaXR5LWZlZWRiYWNrIGVycm9yIjsKICAgICAgICBhdmFpbGFiaWxpdHlFbWFpbC5mb2N1cygpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgY29uc3Qgc3VibWl0QnV0dG9uID0gYXZhaWxhYmlsaXR5Rm9ybS5xdWVyeVNlbGVjdG9yKCJidXR0b24iKTsKCiAgICAgIHRyeSB7CiAgICAgICAgc3VibWl0QnV0dG9uLmRpc2FibGVkID0gdHJ1ZTsKICAgICAgICBhdmFpbGFiaWxpdHlGZWVkYmFjay50ZXh0Q29udGVudCA9ICJTYXZpbmcgeW91ciByZXF1ZXN0Li4uIjsKICAgICAgICBhdmFpbGFiaWxpdHlGZWVkYmFjay5jbGFzc05hbWUgPSAiYXZhaWxhYmlsaXR5LWZlZWRiYWNrIGluZm8iOwoKICAgICAgICAvLyBFdmVyeSB3YWl0bGlzdCBlbnRyeSAoYmFzZSBvciBleHRlcm5hbCBkcml2ZSkgaXMgYWJvdXQgdGhlIFNFTEVDVEVEIGRhdGFjZW50ZXIncyBzdG9jay4KICAgICAgICBjb25zdCBkYXRhY2VudGVyID0gTE9DQVRJT05TW3NlbGVjdGVkTG9jYXRpb25dPy5iYWNrZW5kS2V5OwogICAgICAgIC8vIERhaWx5IG91dC1vZi1zdG9jayBlbnRlcnMgdmlhIHRoZSBjeWNsZSB0YWIgd2l0aG91dCBjaGFuZ2luZyBzZWxlY3RlZEN5Y2xlLCBzbyBrZXkgdGhlCiAgICAgICAgLy8gRGFpbHkgY2FzZSBvZmYgdGhlIHByaWNpbmcgb3B0aW9uOyBvdGhlcndpc2UgbWFwIHRoZSBzZWxlY3RlZCBiaWxsaW5nIGN5Y2xlLgogICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvblR5cGUgPSBjdXJyZW50UHJpY2luZ09wdGlvbiA9PT0gQXZhaWxhYmlsaXR5Tm90aWZpY2F0aW9uVHlwZS5EYWlseQogICAgICAgICAgPyBTdWJzY3JpcHRpb25UeXBlLkRhaWx5CiAgICAgICAgICA6IENZQ0xFX1RPX1NVQlNDUklQVElPTl9UWVBFW3NlbGVjdGVkQ3ljbGVdOwogICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goRU5EUE9JTlRfU1VCU0NSSUJFLCB7CiAgICAgICAgICBtZXRob2Q6ICJQT1NUIiwKICAgICAgICAgIGhlYWRlcnM6IHsgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIiB9LAogICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBlbWFpbCwgcHJpY2luZ09wdGlvbjogY3VycmVudFByaWNpbmdPcHRpb24sIGRhdGFjZW50ZXIsIHN1YnNjcmlwdGlvblR5cGUgfSkKICAgICAgICB9KTsKCiAgICAgICAgaWYgKCFyZXNwb25zZS5vaykgewogICAgICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDI5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiWW91J3JlIGdvaW5nIHRvbyBmYXN0LiBQbGVhc2UgdHJ5IGFnYWluIGxhdGVyLiIpOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgZXJyb3JCb2R5ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpLmNhdGNoKCgpID0+ICh7fSkpOwogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yQm9keT8uZXJyb3IgPz8gIlNvcnJ5LCBzb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSBhZ2FpbiBsYXRlci4iKTsKICAgICAgICB9CgogICAgICAgIGF2YWlsYWJpbGl0eUVtYWlsLnZhbHVlID0gIiI7CiAgICAgICAgZm9ybVN1Ym1pdHRlZFN1Y2Nlc3NmdWxseSA9IHRydWU7CiAgICAgICAgYXZhaWxhYmlsaXR5RmVlZGJhY2sudGV4dENvbnRlbnQgPSAiWW91J3JlIG9uIHRoZSBsaXN0ISBXZSdsbCBlbWFpbCB5b3UgdGhlIG1vbWVudCBhIE1hYyBzcGlucyB1cC4iOwogICAgICAgIGF2YWlsYWJpbGl0eUZlZWRiYWNrLmNsYXNzTmFtZSA9ICJhdmFpbGFiaWxpdHktZmVlZGJhY2sgc3VjY2VzcyI7CgogICAgICAgIHN1Ym1pdEJ1dHRvbi50ZXh0Q29udGVudCA9ICJDbG9zZSI7CiAgICAgICAgc3VibWl0QnV0dG9uLmRpc2FibGVkID0gZmFsc2U7CiAgICAgICAgc3VibWl0QnV0dG9uLnN0eWxlLmJhY2tncm91bmQgPSAicmdiYSgyNTUsMjU1LDI1NSwuMSkiOwogICAgICAgIHN1Ym1pdEJ1dHRvbi5zdHlsZS5jb2xvciA9ICJ2YXIoLS10ZXh0KSI7CiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgYXZhaWxhYmlsaXR5RmVlZGJhY2sudGV4dENvbnRlbnQgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICJTb3JyeSwgc29tZXRoaW5nIHdlbnQgd3JvbmcuIjsKICAgICAgICBhdmFpbGFiaWxpdHlGZWVkYmFjay5jbGFzc05hbWUgPSAiYXZhaWxhYmlsaXR5LWZlZWRiYWNrIGVycm9yIjsKICAgICAgICBzdWJtaXRCdXR0b24uZGlzYWJsZWQgPSBmYWxzZTsKICAgICAgfQogICAgfQoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBHT09HTEUgUkVWSUVXUyBDT05GSUdVUkFUSU9OCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICAgIGNvbnN0IFJFVklFV1NfQ09ORklHID0gewogICAgICAvLyBHb29nbGUgTWFwcyBVUkwgZm9yICJSZWFkIGFsbCByZXZpZXdzIiBsaW5rCiAgICAgIGdvb2dsZU1hcHNVcmw6ICdodHRwczovL21hcHMuYXBwLmdvby5nbC92NTVlZEtEN0syZ2VQaFRoOScsCgogICAgICAvLyBSZXZpZXdzIGRhdGEgLSBVcGRhdGUgdGhlc2UgbWFudWFsbHkgd2hlbiBuZXcgcmV2aWV3cyBjb21lIGluCiAgICAgIGZhbGxiYWNrRGF0YTogewogICAgICAgIHJhdGluZzogNS4wLAogICAgICAgIHRvdGFsUmV2aWV3czogMjgsCiAgICAgICAgcmV2aWV3czogWwogICAgICAgICAgewogICAgICAgICAgICBhdXRob3JfbmFtZTogIkFobWVkIE1vbnNlZiIsCiAgICAgICAgICAgIHJhdGluZzogNSwKICAgICAgICAgICAgdGV4dDogIkV4Y2VsbGVudCBzZXJ2aWNlIGluIGV2ZXJ5IGFzcGVjdC4gUmVzcG9uc2UgdGltZSBpcyBvdXRzdGFuZGluZywgYW5kIHRoZSB0ZWNobmljYWwgc3VwcG9ydCB0ZWFtIGlzIHZlcnkgY29vcGVyYXRpdmUgYW5kIGZvbGxvd3MgdXAgdW50aWwgdGhlIGlzc3VlIGlzIGNvbXBsZXRlbHkgcmVzb2x2ZWQuIEFueSBpbnF1aXJ5IG9yIHByb2JsZW0gaXMgaGFuZGxlZCB3aXRoIHByb2Zlc3Npb25hbGlzbSBhbmQgZ3JlYXQgY2FyZS4gQSBzbW9vdGggZXhwZXJpZW5jZSBhbmQgdHJ1bHkgZXhjZXB0aW9uYWwgc2VydmljZSDigJQgaGlnaGx5IHJlY29tbWVuZGVkIHdpdGhvdXQgaGVzaXRhdGlvbi4iLAogICAgICAgICAgICByZWxhdGl2ZV90aW1lX2Rlc2NyaXB0aW9uOiAiNiBkYXlzIGFnbyIsCiAgICAgICAgICAgIHByb2ZpbGVfcGhvdG9fdXJsOiBudWxsCiAgICAgICAgICB9LAogICAgICAgICAgewogICAgICAgICAgICBhdXRob3JfbmFtZTogIkVsZW5hIFNhbGFkaW5pIiwKICAgICAgICAgICAgcmF0aW5nOiA1LAogICAgICAgICAgICB0ZXh0OiAiR3JlYXQgYW5kIHZlcnkgaGVscGZ1bCBzZXJ2aWNlISBUaGFuayB5b3UuIiwKICAgICAgICAgICAgcmVsYXRpdmVfdGltZV9kZXNjcmlwdGlvbjogImEgd2VlayBhZ28iLAogICAgICAgICAgICBwcm9maWxlX3Bob3RvX3VybDogbnVsbAogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgYXV0aG9yX25hbWU6ICJFbWFtYSBTaGFrZXJ5IiwKICAgICAgICAgICAgcmF0aW5nOiA1LAogICAgICAgICAgICB0ZXh0OiAiU3VwZXIgZWFzeSB0byByZW50IGEgTWFjISBGYXN0IGRlbGl2ZXJ5IGFuZCBncmVhdCBjb25kaXRpb24uIEhpZ2hseSByZWNvbW1lbmQiLAogICAgICAgICAgICByZWxhdGl2ZV90aW1lX2Rlc2NyaXB0aW9uOiAiMiB3ZWVrcyBhZ28iLAogICAgICAgICAgICBwcm9maWxlX3Bob3RvX3VybDogbnVsbAogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgYXV0aG9yX25hbWU6ICJNYWxhayBBbHdhemVlciIsCiAgICAgICAgICAgIHJhdGluZzogNSwKICAgICAgICAgICAgdGV4dDogIkdyZWF0IHByaWNpbmcsIGVhc3kgc2V0dXAsIGFuZCBvdXRzdGFuZGluZyBjdXN0b21lciBjb21tdW5pY2F0aW9uLiBTdXBwb3J0IHdhcyBmYXN0IGFuZCB2ZXJ5IGhlbHBmdWwuIEhpZ2hseSByZWNvbW1lbmRlZCEiLAogICAgICAgICAgICByZWxhdGl2ZV90aW1lX2Rlc2NyaXB0aW9uOiAiMiB3ZWVrcyBhZ28iLAogICAgICAgICAgICBwcm9maWxlX3Bob3RvX3VybDogbnVsbAogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgYXV0aG9yX25hbWU6ICJTdW1hbiIsCiAgICAgICAgICAgIHJhdGluZzogNSwKICAgICAgICAgICAgdGV4dDogIlRoZSBwZXJmb3JtYW5jZSBhcmUgYXdlc29tZSBvZiB0aGUgbWFjLiBBbmQgaSBuZXZlciBmYWNlIGFueSBpc3N1ZSBvbiBvbmxpbmUgbWFjIHJ1bm5pbmcgb24gY2xvdWQuIFRoZSBiZXN0IHBhcnQgaXMgaXQncyBhZmZvcmRhYmxlIGZvciBtZSB0byBjb2RlIG9uIG1hYyBmcm9tIG15IFdpbmRvd3MgcGMuIiwKICAgICAgICAgICAgcmVsYXRpdmVfdGltZV9kZXNjcmlwdGlvbjogIjQgd2Vla3MgYWdvIiwKICAgICAgICAgICAgcHJvZmlsZV9waG90b191cmw6IG51bGwKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgIGF1dGhvcl9uYW1lOiAiSGFzc2FuIEFMLU9yYWliaSIsCiAgICAgICAgICAgIHJhdGluZzogNSwKICAgICAgICAgICAgdGV4dDogIkdyZWF0IHNlcnZpY2Ugd2l0aCBleGNlbGxlbnQgc3VwcG9ydC4gVGhlIE1hYyBNaW5pIE00IHJ1bnMgc21vb3RobHkgYW5kIHRoZSBzZXR1cCB3YXMgcXVpY2suIEhpZ2hseSByZWNvbW1lbmRlZCBmb3IgZGV2ZWxvcGVycyEiLAogICAgICAgICAgICByZWxhdGl2ZV90aW1lX2Rlc2NyaXB0aW9uOiAiYSBtb250aCBhZ28iLAogICAgICAgICAgICBwcm9maWxlX3Bob3RvX3VybDogbnVsbAogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfQogICAgfTsKCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gUkVWSUVXUyBDQVJPVVNFTAogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICBsZXQgcmV2aWV3c0RhdGEgPSBudWxsOwogICAgbGV0IGN1cnJlbnRSZXZpZXdTbGlkZSA9IDA7CgogICAgZnVuY3Rpb24gZ2VuZXJhdGVTdGFyc0h0bWwocmF0aW5nLCBzaXplID0gMTYpIHsKICAgICAgbGV0IGh0bWwgPSAnJzsKICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gNTsgaSsrKSB7CiAgICAgICAgaWYgKGkgPD0gcmF0aW5nKSB7CiAgICAgICAgICBodG1sICs9IGA8c3ZnIHdpZHRoPSIke3NpemV9IiBoZWlnaHQ9IiR7c2l6ZX0iIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZCQkMwNCI+PHBhdGggZD0iTTEyIDJsMy4wOSA2LjI2TDIyIDkuMjdsLTUgNC44NyAxLjE4IDYuODhMMTIgMTcuNzdsLTYuMTggMy4yNUw3IDE0LjE0IDIgOS4yN2w2LjkxLTEuMDFMMTIgMnoiLz48L3N2Zz5gOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBodG1sICs9IGA8c3ZnIHdpZHRoPSIke3NpemV9IiBoZWlnaHQ9IiR7c2l6ZX0iIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0icmdiYSgyNTUsMjU1LDI1NSwwLjIpIj48cGF0aCBkPSJNMTIgMmwzLjA5IDYuMjZMMjIgOS4yN2wtNSA0Ljg3IDEuMTggNi44OEwxMiAxNy43N2wtNi4xOCAzLjI1TDcgMTQuMTQgMiA5LjI3bDYuOTEtMS4wMUwxMiAyeiIvPjwvc3ZnPmA7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBodG1sOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFJlbGF0aXZlVGltZSh0aW1lc3RhbXApIHsKICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKSAvIDEwMDA7CiAgICAgIGNvbnN0IGRpZmYgPSBub3cgLSB0aW1lc3RhbXA7CgogICAgICBpZiAoZGlmZiA8IDg2NDAwKSByZXR1cm4gJ1RvZGF5JzsKICAgICAgaWYgKGRpZmYgPCA4NjQwMCAqIDIpIHJldHVybiAnWWVzdGVyZGF5JzsKICAgICAgaWYgKGRpZmYgPCA4NjQwMCAqIDcpIHJldHVybiBgJHtNYXRoLmZsb29yKGRpZmYgLyA4NjQwMCl9IGRheXMgYWdvYDsKICAgICAgaWYgKGRpZmYgPCA4NjQwMCAqIDMwKSByZXR1cm4gYCR7TWF0aC5mbG9vcihkaWZmIC8gKDg2NDAwICogNykpfSB3ZWVrcyBhZ29gOwogICAgICBpZiAoZGlmZiA8IDg2NDAwICogMzY1KSByZXR1cm4gYCR7TWF0aC5mbG9vcihkaWZmIC8gKDg2NDAwICogMzApKX0gbW9udGhzIGFnb2A7CiAgICAgIHJldHVybiBgJHtNYXRoLmZsb29yKGRpZmYgLyAoODY0MDAgKiAzNjUpKX0geWVhcnMgYWdvYDsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRJbml0aWFscyhuYW1lKSB7CiAgICAgIHJldHVybiBuYW1lLnNwbGl0KCcgJykubWFwKG4gPT4gblswXSkuam9pbignJykudG9VcHBlckNhc2UoKS5zdWJzdHJpbmcoMCwgMik7CiAgICB9CgogICAgZnVuY3Rpb24gcmVuZGVyUmV2aWV3Q2FyZChyZXZpZXcpIHsKICAgICAgY29uc3QgaW5pdGlhbHMgPSBnZXRJbml0aWFscyhyZXZpZXcuYXV0aG9yX25hbWUpOwogICAgICBjb25zdCByZWxhdGl2ZVRpbWUgPSByZXZpZXcucmVsYXRpdmVfdGltZV9kZXNjcmlwdGlvbiB8fCBnZXRSZWxhdGl2ZVRpbWUocmV2aWV3LnRpbWUpOwoKICAgICAgcmV0dXJuIGAKICAgICAgICA8ZGl2IGNsYXNzPSJyZXZpZXctY2FyZCI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJyZXZpZXctaGVhZGVyIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icmV2aWV3ZXItYXZhdGFyIj4KICAgICAgICAgICAgICAke3Jldmlldy5wcm9maWxlX3Bob3RvX3VybAogICAgICAgICAgICAgICAgPyBgPGltZyBzcmM9IiR7cmV2aWV3LnByb2ZpbGVfcGhvdG9fdXJsfSIgYWx0PSIke3Jldmlldy5hdXRob3JfbmFtZX0iIC8+YAogICAgICAgICAgICAgICAgOiBpbml0aWFscwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InJldmlld2VyLWluZm8iPgogICAgICAgICAgICAgIDxkaXYgY2xhc3M9InJldmlld2VyLW5hbWUiPiR7cmV2aWV3LmF1dGhvcl9uYW1lfTwvZGl2PgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPGRpdiBjbGFzcz0icmV2aWV3LXN0YXJzIj4KICAgICAgICAgICAgJHtnZW5lcmF0ZVN0YXJzSHRtbChyZXZpZXcucmF0aW5nKX0KICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPGRpdiBjbGFzcz0icmV2aWV3LXRleHQiPiR7cmV2aWV3LnRleHR9PC9kaXY+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJyZXZpZXctZ29vZ2xlLWljb24iPgogICAgICAgICAgICA8c3ZnIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIxOCI+CiAgICAgICAgICAgICAgPHBhdGggZmlsbD0iIzQyODVGNCIgZD0iTTIyLjU2IDEyLjI1YzAtLjc4LS4wNy0xLjUzLS4yLTIuMjVIMTJ2NC4yNmg1LjkyYy0uMjYgMS4zNy0xLjA0IDIuNTMtMi4yMSAzLjMxdjIuNzdoMy41N2MyLjA4LTEuOTIgMy4yOC00Ljc0IDMuMjgtOC4wOXoiLz4KICAgICAgICAgICAgICA8cGF0aCBmaWxsPSIjMzRBODUzIiBkPSJNMTIgMjNjMi45NyAwIDUuNDYtLjk4IDcuMjgtMi42NmwtMy41Ny0yLjc3Yy0uOTguNjYtMi4yMyAxLjA2LTMuNzEgMS4wNi0yLjg2IDAtNS4yOS0xLjkzLTYuMTYtNC41M0gyLjE4djIuODRDMy45OSAyMC41MyA3LjcgMjMgMTIgMjN6Ii8+CiAgICAgICAgICAgICAgPHBhdGggZmlsbD0iI0ZCQkMwNSIgZD0iTTUuODQgMTQuMDljLS4yMi0uNjYtLjM1LTEuMzYtLjM1LTIuMDlzLjEzLTEuNDMuMzUtMi4wOVY3LjA3SDIuMThDMS40MyA4LjU1IDEgMTAuMjIgMSAxMnMuNDMgMy40NSAxLjE4IDQuOTNsMi44NS0yLjIyLjgxLS42MnoiLz4KICAgICAgICAgICAgICA8cGF0aCBmaWxsPSIjRUE0MzM1IiBkPSJNMTIgNS4zOGMxLjYyIDAgMy4wNi41NiA0LjIxIDEuNjRsMy4xNS0zLjE1QzE3LjQ1IDIuMDkgMTQuOTcgMSAxMiAxIDcuNyAxIDMuOTkgMy40NyAyLjE4IDcuMDdsMy42NiAyLjg0Yy44Ny0yLjYgMy4zLTQuNTMgNi4xNi00LjUzeiIvPgogICAgICAgICAgICA8L3N2Zz4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICBgOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbmRlclJldmlld3MoZGF0YSkgewogICAgICByZXZpZXdzRGF0YSA9IGRhdGE7CgogICAgICAvLyBVcGRhdGUgc3VtbWFyeSAoc21hbGxlciBzdGFycyBmb3IgaGVhZGVyKQogICAgICBjb25zdCBhdmdSYXRpbmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdmdSYXRpbmcnKTsKICAgICAgY29uc3QgYXZnU3RhcnNFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhdmdTdGFycycpOwogICAgICBjb25zdCBjYXJvdXNlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZXZpZXdzQ2Fyb3VzZWwnKTsKCiAgICAgIGlmICghYXZnUmF0aW5nRWwgfHwgIWF2Z1N0YXJzRWwgfHwgIWNhcm91c2VsKSB7CiAgICAgICAgY29uc29sZS5lcnJvcignUmVudGFNYWMgUHJpY2luZzogUmV2aWV3cyBlbGVtZW50cyBub3QgZm91bmQnKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIGF2Z1JhdGluZ0VsLnRleHRDb250ZW50ID0gZGF0YS5yYXRpbmcudG9GaXhlZCgxKTsKICAgICAgYXZnU3RhcnNFbC5pbm5lckhUTUwgPSBnZW5lcmF0ZVN0YXJzSHRtbChNYXRoLnJvdW5kKGRhdGEucmF0aW5nKSwgMTgpOwoKICAgICAgLy8gUmVuZGVyIHJldmlldyBjYXJkcyAoZHVwbGljYXRlIGZvciBpbmZpbml0ZSBzY3JvbGwpCiAgICAgIGNvbnN0IHJldmlld3NIdG1sID0gZGF0YS5yZXZpZXdzLm1hcChyZW5kZXJSZXZpZXdDYXJkKS5qb2luKCcnKTsKICAgICAgLy8gRHVwbGljYXRlIHJldmlld3MgZm9yIHNlYW1sZXNzIGluZmluaXRlIHNjcm9sbAogICAgICBjYXJvdXNlbC5pbm5lckhUTUwgPSByZXZpZXdzSHRtbCArIHJldmlld3NIdG1sOwogICAgfQoKICAgIGZ1bmN0aW9uIGxvYWRHb29nbGVSZXZpZXdzKCkgewogICAgICAvLyBMb2FkIHJldmlld3MgZnJvbSBjb25maWcKICAgICAgcmVuZGVyUmV2aWV3cyhSRVZJRVdTX0NPTkZJRy5mYWxsYmFja0RhdGEpOwogICAgfQoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBFTlRFUlBSSVNFIFBSSUNJTkcgQ0FMQ1VMQVRPUgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICBsZXQgcXVhbnRpdHlTbGlkZXIsIGR1cmF0aW9uU2xpZGVyLCBxdWFudGl0eVZhbHVlLCBkdXJhdGlvblZhbHVlLAogICAgICAgIHF1YW50aXR5RGlzY291bnRCYWRnZSwgZHVyYXRpb25EaXNjb3VudEJhZGdlLCBlbnRlcnByaXNlUHJpY2UsCiAgICAgICAgZGlzY291bnRCYWRnZUVsLCBwcmljZUJyZWFrZG93bkVudGVycHJpc2UsIG5vbkN1bXVsYXRpdmVOb3RpY2U7CgogICAgY29uc3QgQkFTRV9QUklDRV9QRVJfTU9OVEggPSAxMTk7CiAgICBsZXQgcHJldmlvdXNRdWFudGl0eURpc2NvdW50ID0gMDsKICAgIGxldCBwcmV2aW91c1RpbWVEaXNjb3VudCA9IDA7CgogICAgZnVuY3Rpb24gY2FsY3VsYXRlRW50ZXJwcmlzZVByaWNlKCkgewogICAgICBpZiAoIXF1YW50aXR5U2xpZGVyIHx8ICFkdXJhdGlvblNsaWRlcikgcmV0dXJuOwoKICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChxdWFudGl0eVNsaWRlci52YWx1ZSk7CiAgICAgIGNvbnN0IGR1cmF0aW9uID0gcGFyc2VJbnQoZHVyYXRpb25TbGlkZXIudmFsdWUpOwoKICAgICAgLy8gRGV0ZXJtaW5lIHByaWNlIHBlciBtb250aCBiYXNlZCBvbiBkdXJhdGlvbgogICAgICBsZXQgcHJpY2VQZXJNb250aCA9IEJBU0VfUFJJQ0VfUEVSX01PTlRIOwogICAgICBsZXQgdGltZURpc2NvdW50ID0gMDsKCiAgICAgIGlmIChkdXJhdGlvbiA+PSAzICYmIGR1cmF0aW9uIDwgNikgewogICAgICAgIC8vIDMtNSBtb250aHM6IE1hdGNoIDMtbW9udGggcGxhbiBwcmljaW5nICgkMzM5IC8gMyA9ICQxMTMuMDAvbW9udGgpCiAgICAgICAgcHJpY2VQZXJNb250aCA9IDMzOSAvIDM7CiAgICAgICAgdGltZURpc2NvdW50ID0gMC4wNTsKICAgICAgfSBlbHNlIGlmIChkdXJhdGlvbiA+PSA2KSB7CiAgICAgICAgLy8gNisgbW9udGhzOiBNYXRjaCA2LW1vbnRoIHBsYW4gcHJpY2luZyAoJDYzOSAvIDYgPSAkMTA2LjUwL21vbnRoKQogICAgICAgIHByaWNlUGVyTW9udGggPSA2MzkgLyA2OwogICAgICAgIHRpbWVEaXNjb3VudCA9IDAuMTA7CiAgICAgIH0KCiAgICAgIC8vIENhbGN1bGF0ZSBxdWFudGl0eS1iYXNlZCBkaXNjb3VudAogICAgICBsZXQgcXVhbnRpdHlEaXNjb3VudCA9IDA7CiAgICAgIGlmIChxdWFudGl0eSA+PSA1ICYmIHF1YW50aXR5IDw9IDE0KSB7CiAgICAgICAgcXVhbnRpdHlEaXNjb3VudCA9IDAuMDU7IC8vIDUlIGRpc2NvdW50CiAgICAgIH0gZWxzZSBpZiAocXVhbnRpdHkgPj0gMTUpIHsKICAgICAgICBxdWFudGl0eURpc2NvdW50ID0gMC4xMDsgLy8gMTAlIGRpc2NvdW50CiAgICAgIH0KCiAgICAgIC8vIEFwcGx5IHRoZSBoaWdoZXIgZGlzY291bnQKICAgICAgbGV0IGZpbmFsUHJpY2VQZXJNb250aCA9IHByaWNlUGVyTW9udGg7CiAgICAgIGxldCBhcHBsaWVkRGlzY291bnQgPSB0aW1lRGlzY291bnQ7CgogICAgICBpZiAocXVhbnRpdHlEaXNjb3VudCA+IHRpbWVEaXNjb3VudCkgewogICAgICAgIGZpbmFsUHJpY2VQZXJNb250aCA9IEJBU0VfUFJJQ0VfUEVSX01PTlRIICogKDEgLSBxdWFudGl0eURpc2NvdW50KTsKICAgICAgICBhcHBsaWVkRGlzY291bnQgPSBxdWFudGl0eURpc2NvdW50OwogICAgICB9CgogICAgICAvLyBVcGRhdGUgcXVhbnRpdHkgZGlzY291bnQgYmFkZ2UKICAgICAgaWYgKHF1YW50aXR5RGlzY291bnQgPiAwKSB7CiAgICAgICAgY29uc3QgcXVhbnRpdHlQZXJjZW50ID0gTWF0aC5yb3VuZChxdWFudGl0eURpc2NvdW50ICogMTAwKTsKICAgICAgICBxdWFudGl0eURpc2NvdW50QmFkZ2UudGV4dENvbnRlbnQgPSBxdWFudGl0eVBlcmNlbnQgKyAiJSBPRkYiOwogICAgICAgIHF1YW50aXR5RGlzY291bnRCYWRnZS5jbGFzc0xpc3QuYWRkKCJhY3RpdmUiKTsKCiAgICAgICAgaWYgKHF1YW50aXR5RGlzY291bnQgIT09IHByZXZpb3VzUXVhbnRpdHlEaXNjb3VudCkgewogICAgICAgICAgcXVhbnRpdHlEaXNjb3VudEJhZGdlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgdm9pZCBxdWFudGl0eURpc2NvdW50QmFkZ2Uub2Zmc2V0V2lkdGg7CiAgICAgICAgICBxdWFudGl0eURpc2NvdW50QmFkZ2UuY2xhc3NMaXN0LmFkZCgiYm91bmNlIik7CiAgICAgICAgICBxdWFudGl0eVZhbHVlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgdm9pZCBxdWFudGl0eVZhbHVlLm9mZnNldFdpZHRoOwogICAgICAgICAgcXVhbnRpdHlWYWx1ZS5jbGFzc0xpc3QuYWRkKCJib3VuY2UiKTsKCiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICAgICAgcXVhbnRpdHlEaXNjb3VudEJhZGdlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgICBxdWFudGl0eVZhbHVlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgfSwgNjAwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcXVhbnRpdHlEaXNjb3VudEJhZGdlLmNsYXNzTGlzdC5yZW1vdmUoImFjdGl2ZSIpOwogICAgICB9CgogICAgICAvLyBVcGRhdGUgZHVyYXRpb24gZGlzY291bnQgYmFkZ2UKICAgICAgaWYgKHRpbWVEaXNjb3VudCA+IDApIHsKICAgICAgICBjb25zdCB0aW1lUGVyY2VudCA9IE1hdGgucm91bmQodGltZURpc2NvdW50ICogMTAwKTsKICAgICAgICBkdXJhdGlvbkRpc2NvdW50QmFkZ2UudGV4dENvbnRlbnQgPSB0aW1lUGVyY2VudCArICIlIE9GRiI7CiAgICAgICAgZHVyYXRpb25EaXNjb3VudEJhZGdlLmNsYXNzTGlzdC5hZGQoImFjdGl2ZSIpOwoKICAgICAgICBpZiAodGltZURpc2NvdW50ICE9PSBwcmV2aW91c1RpbWVEaXNjb3VudCkgewogICAgICAgICAgZHVyYXRpb25EaXNjb3VudEJhZGdlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgdm9pZCBkdXJhdGlvbkRpc2NvdW50QmFkZ2Uub2Zmc2V0V2lkdGg7CiAgICAgICAgICBkdXJhdGlvbkRpc2NvdW50QmFkZ2UuY2xhc3NMaXN0LmFkZCgiYm91bmNlIik7CiAgICAgICAgICBkdXJhdGlvblZhbHVlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgdm9pZCBkdXJhdGlvblZhbHVlLm9mZnNldFdpZHRoOwogICAgICAgICAgZHVyYXRpb25WYWx1ZS5jbGFzc0xpc3QuYWRkKCJib3VuY2UiKTsKCiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsKICAgICAgICAgICAgZHVyYXRpb25EaXNjb3VudEJhZGdlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgICBkdXJhdGlvblZhbHVlLmNsYXNzTGlzdC5yZW1vdmUoImJvdW5jZSIpOwogICAgICAgICAgfSwgNjAwKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZHVyYXRpb25EaXNjb3VudEJhZGdlLmNsYXNzTGlzdC5yZW1vdmUoImFjdGl2ZSIpOwogICAgICB9CgogICAgICAvLyBTaG93IG5vbi1jdW11bGF0aXZlIG5vdGljZSB3aGVuIGJvdGggaGF2ZSBkaXNjb3VudHMKICAgICAgaWYgKG5vbkN1bXVsYXRpdmVOb3RpY2UpIHsKICAgICAgICBub25DdW11bGF0aXZlTm90aWNlLnN0eWxlLmRpc3BsYXkgPSAocXVhbnRpdHlEaXNjb3VudCA+IDAgJiYgdGltZURpc2NvdW50ID4gMCkgPyAiYmxvY2siIDogIm5vbmUiOwogICAgICB9CgogICAgICAvLyBHZW5lcmF0ZSBkaXNjb3VudCB0ZXh0CiAgICAgIGxldCBkaXNjb3VudFRleHQgPSAiU3RhbmRhcmQgcHJpY2luZyI7CiAgICAgIGlmIChhcHBsaWVkRGlzY291bnQgPiAwKSB7CiAgICAgICAgZGlzY291bnRUZXh0ID0gTWF0aC5yb3VuZChhcHBsaWVkRGlzY291bnQgKiAxMDApICsgIiUgZGlzY291bnQgYXBwbGllZCI7CiAgICAgIH0KCiAgICAgIC8vIENhbGN1bGF0ZSB0b3RhbCBwcmljZQogICAgICBjb25zdCB0b3RhbFByaWNlID0gcXVhbnRpdHkgKiBkdXJhdGlvbiAqIGZpbmFsUHJpY2VQZXJNb250aDsKCiAgICAgIC8vIFVwZGF0ZSBVSQogICAgICBxdWFudGl0eVZhbHVlLnRleHRDb250ZW50ID0gcXVhbnRpdHkgPj0gMTUgPyAiMTUrIiA6IHF1YW50aXR5OwogICAgICBkdXJhdGlvblZhbHVlLnRleHRDb250ZW50ID0gZHVyYXRpb247CiAgICAgIGVudGVycHJpc2VQcmljZS50ZXh0Q29udGVudCA9ICIkIiArIHRvdGFsUHJpY2UudG9Mb2NhbGVTdHJpbmcoJ2VuLVVTJywgeyBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IDAsIG1heGltdW1GcmFjdGlvbkRpZ2l0czogMCB9KTsKCiAgICAgIGlmIChhcHBsaWVkRGlzY291bnQgPiAwKSB7CiAgICAgICAgZGlzY291bnRCYWRnZUVsLmNsYXNzTGlzdC5hZGQoImFjdGl2ZSIpOwogICAgICB9IGVsc2UgewogICAgICAgIGRpc2NvdW50QmFkZ2VFbC5jbGFzc0xpc3QucmVtb3ZlKCJhY3RpdmUiKTsKICAgICAgfQogICAgICBkaXNjb3VudEJhZGdlRWwudGV4dENvbnRlbnQgPSBkaXNjb3VudFRleHQ7CgogICAgICBwcmljZUJyZWFrZG93bkVudGVycHJpc2UudGV4dENvbnRlbnQgPSAiJCIgKyBmaW5hbFByaWNlUGVyTW9udGgudG9GaXhlZCgyKSArICIvbW9udGggcGVyIGluc3RhbmNlIjsKCiAgICAgIHByZXZpb3VzUXVhbnRpdHlEaXNjb3VudCA9IHF1YW50aXR5RGlzY291bnQ7CiAgICAgIHByZXZpb3VzVGltZURpc2NvdW50ID0gdGltZURpc2NvdW50OwogICAgfQoKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyBOQVZJR0FUSU9OIEhFTFBFUgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICBmdW5jdGlvbiBuYXZpZ2F0ZVdpdGhMYW5ndWFnZSh0YXJnZXRQYXRoKSB7CiAgICAgIGNvbnN0IGN1cnJlbnRQYXRoID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lOwogICAgICBjb25zdCBsYW5nQ29kZXMgPSBbJ3RyJywgJ2FyJywgJ2ZyJywgJ3B0JywgJ2VzJywgJ2VuJ107CiAgICAgIGNvbnN0IHBhdGhTZWdtZW50cyA9IGN1cnJlbnRQYXRoLnNwbGl0KCcvJykuZmlsdGVyKHNlZ21lbnQgPT4gc2VnbWVudC5sZW5ndGggPiAwKTsKCiAgICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoID4gMCAmJiBsYW5nQ29kZXMuaW5jbHVkZXMocGF0aFNlZ21lbnRzWzBdLnRvTG93ZXJDYXNlKCkpKSB7CiAgICAgICAgY29uc3QgbGFuZ0NvZGUgPSBwYXRoU2VnbWVudHNbMF07CiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSBgLyR7bGFuZ0NvZGV9JHt0YXJnZXRQYXRofWA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSB0YXJnZXRQYXRoOwogICAgICB9CiAgICB9CgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIExPQ0FUSU9OIEZVTkNUSU9OUwogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICBmdW5jdGlvbiByZW5kZXJMb2NhdGlvblRhYnMoKSB7CiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2NhdGlvblRhYnMnKTsKICAgICAgaWYgKCFjb250YWluZXIpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCdSZW50YU1hYyBQcmljaW5nOiAjbG9jYXRpb25UYWJzIGVsZW1lbnQgbm90IGZvdW5kJyk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSAnJzsKCiAgICAgIE9iamVjdC5lbnRyaWVzKExPQ0FUSU9OUykuZm9yRWFjaCgoW2tleSwgbG9jXSkgPT4gewogICAgICAgIGNvbnN0IHRhYiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIGxldCBjbGFzc2VzID0gJ2N5Y2xlLXRhYic7CiAgICAgICAgaWYgKGtleSA9PT0gc2VsZWN0ZWRMb2NhdGlvbiAmJiBsb2MuYXZhaWxhYmxlKSBjbGFzc2VzICs9ICcgYWN0aXZlJzsKICAgICAgICB0YWIuY2xhc3NOYW1lID0gY2xhc3NlczsKICAgICAgICB0YWIuZGF0YXNldC5sb2NhdGlvbiA9IGtleTsKCiAgICAgICAgdGFiLmlubmVySFRNTCA9IGAKICAgICAgICAgIDxzcGFuIGNsYXNzPSJjeWNsZS1uYW1lIj4ke2xvYy5mbGFnfSAke2xvYy5jb250aW5lbnR9PC9zcGFuPgogICAgICAgICAgPHNwYW4gY2xhc3M9ImN5Y2xlLXByaWNlIj4ke2xvYy5jb3VudHJ5fTwvc3Bhbj4KICAgICAgICBgOwoKICAgICAgICBpZiAobG9jLmF2YWlsYWJsZSkgewogICAgICAgICAgdGFiLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gewogICAgICAgICAgICB1c2VySW50ZXJhY3RlZFdpdGhMb2NhdGlvbiA9IHRydWU7CiAgICAgICAgICAgIHNlbGVjdExvY2F0aW9uKGtleSk7CiAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0YWIpOwogICAgICB9KTsKICAgIH0KCiAgICBmdW5jdGlvbiBzZWxlY3RMb2NhdGlvbihsb2NhdGlvbktleSkgewogICAgICBjb25zdCBsb2MgPSBMT0NBVElPTlNbbG9jYXRpb25LZXldOwogICAgICBpZiAoIWxvYyB8fCAhbG9jLmF2YWlsYWJsZSkgcmV0dXJuOwogICAgICBpZiAobG9jYXRpb25LZXkgIT09IHNlbGVjdGVkTG9jYXRpb24pIHsKICAgICAgICAvLyBUaGUgRGFpbHkgbm90aWNlIGFuc3dlcnMgYSB0YXAgaW4gT05FIHJlZ2lvbjsgYSBuZXcgcmVnaW9uIHN0YXJ0cyBjbGVhbi4KICAgICAgICBkYWlseU5vdGljZVJlcXVlc3RlZCA9IGZhbHNlOwogICAgICB9CiAgICAgIHNlbGVjdGVkTG9jYXRpb24gPSBsb2NhdGlvbktleTsKICAgICAgcmVuZGVyTG9jYXRpb25UYWJzKCk7CiAgICAgIC8vIEF2YWlsYWJpbGl0eSBjb3VudHMgYXJlIHBlci1EQyDigJQgcmVjb21wdXRlIGZyb20gdGhlIGNhY2hlZCBwYXlsb2FkIHNvIHRoZQogICAgICAvLyBzdG9yYWdlIHRpbGVzLCBkYWlseS1wbGFuIGdhdGUsIGFuZCBDVEEgYnV0dG9uIHJlZmxlY3QgdGhlIG5ldyBsb2NhdGlvbi4KICAgICAgYXBwbHlBdmFpbGFiaWxpdHlGb3JTZWxlY3RlZExvY2F0aW9uKCk7CiAgICB9CgogICAgLy8g4pqg77iPIEtFRVAgSU4gU1lOQyB3aXRoIHRoZSB1c2VyLWFwcCBwcmljaW5nIHBhZ2U6CiAgICAvLyAgICBSZW50QW1hYy9SZW50QW1hYy1Vc2VyL2FwcC9bbG9jYWxlXS9kYXNoYm9hcmQvcHJpY2luZy9wYWdlLnRzeCAgKGdlb1RvRGF0YWNlbnRlciAvIENZUFJVU19QUkVGRVJSRURfQ09VTlRSSUVTKQogICAgLy8gQm90aCBzdXJmYWNlcyBtdXN0IHJvdXRlIHRoZSBzYW1lIHdheS4gSWYgeW91IGNoYW5nZSB0aGUgY291bnRyeSBsaXN0IG9yIGNvbnRpbmVudCBtYXBwaW5nCiAgICAvLyBoZXJlLCBtaXJyb3IgaXQgdGhlcmUgKGFuZCB2aWNlLXZlcnNhKS4KICAgIC8vCiAgICAvLyBDb3VudHJpZXMgdGhhdCBzaXQgaW4gY29udGluZW50ICJBc2lhIiBidXQgYXJlIGdlb2dyYXBoaWNhbGx5IGNsb3Nlc3QgdG8gb3VyIEN5cHJ1cwogICAgLy8gKExpbWFzc29sKSBkYXRhY2VudGVyIHJhdGhlciB0aGFuIE11bWJhaS4gV2l0aG91dCB0aGlzIG92ZXJyaWRlLCBpcGFwaS5jbydzIGNvbnRpbmVudAogICAgLy8gY29kZSByb3V0ZXMgdGhlIHdob2xlIE5lYXIgRWFzdCDigJQgVHVya2V5LCB0aGUgTGV2YW50LCBtdWNoIG9mIEFyYWJpYSwgdGhlIENhdWNhc3VzIGFuZAogICAgLy8gSXJhbiDigJQgdG8gSW5kaWEsIHdoaWNoIGlzIHRoZSB3cm9uZyAoZmFyKSBkYXRhY2VudGVyIChlLmcuIEFua2FyYeKGkkN5cHJ1cyB+NTgwIGttIHZzCiAgICAvLyB+NCw0MDAga20gdG8gTXVtYmFpKS4gSVNPLTMxNjYtMSBhbHBoYS0yIGNvdW50cnkgY29kZXMuCiAgICAvLyBUaGUgd2hvbGUgR3VsZiAoaW5jbC4gVUFFL09tYW4pIHJvdXRlcyB0byBDeXBydXMgYnkgYnVzaW5lc3MgZGVjaXNpb24sIGV2ZW4gdGhvdWdoCiAgICAvLyBNdW1iYWkgaXMgbWFyZ2luYWxseSBjbG9zZXIgdG8gdGhlIGVhc3Rlcm5tb3N0IHN0YXRlcy4KICAgIGNvbnN0IENZUFJVU19QUkVGRVJSRURfQ09VTlRSSUVTID0gbmV3IFNldChbCiAgICAgICdDWScsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ3lwcnVzCiAgICAgICdUUicsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHVya2V5CiAgICAgICdTWScsICdMQicsICdJTCcsICdQUycsICdKTycsICAgICAgICAgICAgICAgLy8gTGV2YW50CiAgICAgICdJUScsICdJUicsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXJhcSwgSXJhbgogICAgICAnU0EnLCAnS1cnLCAnQkgnLCAnUUEnLCAnQUUnLCAnT00nLCAnWUUnLCAgIC8vIEFyYWJpYW4gcGVuaW5zdWxhIC8gR3VsZgogICAgICAnQU0nLCAnR0UnLCAnQVonLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhdWNhc3VzCiAgICBdKTsKCiAgICAvLyBNYXBzIHRoZSB2aXNpdG9yJ3MgZ2VvIChjb3VudHJ5IGZpcnN0LCB0aGVuIGNvbnRpbmVudCkgdG8gdGhlIGNsb3Nlc3QgYXZhaWxhYmxlIHJlZ2lvbi4KICAgIC8vIE9ubHkgcmV0dXJuIGEgdmFsdWUgd2hlbiB3ZSBhY3R1YWxseSB3YW50IHRvIGF1dG8tc3dpdGNoIGZyb20gdGhlIEN5cHJ1cyBkZWZhdWx0LgogICAgZnVuY3Rpb24gZ2VvVG9Mb2NhdGlvbihjb3VudHJ5Q29kZSwgY29udGluZW50Q29kZSkgewogICAgICAvLyBOZWFyLUVhc3QgLyBDYXVjYXN1cyBjb3VudHJpZXMgYXJlIGluIGNvbnRpbmVudCAiQXNpYSIgYnV0IGFyZSBuZWFyZXN0IHRvIEN5cHJ1cy4KICAgICAgaWYgKGNvdW50cnlDb2RlICYmIENZUFJVU19QUkVGRVJSRURfQ09VTlRSSUVTLmhhcyhjb3VudHJ5Q29kZS50b1VwcGVyQ2FzZSgpKSkgewogICAgICAgIHJldHVybiBudWxsOyAvLyBrZWVwIHRoZSBDeXBydXMgZGVmYXVsdAogICAgICB9CiAgICAgIHN3aXRjaCAoY29udGluZW50Q29kZSkgewogICAgICAgIGNhc2UgJ0FTJzogLy8gQXNpYQogICAgICAgICAgcmV0dXJuICdpbmRpYSc7CiAgICAgICAgY2FzZSAnTkEnOiAvLyBOb3J0aCBBbWVyaWNhCiAgICAgICAgY2FzZSAnU0EnOiAvLyBTb3V0aCBBbWVyaWNhCiAgICAgICAgY2FzZSAnT0MnOiAvLyBPY2VhbmlhIOKAlCBUZXhhcyBieSBidXNpbmVzcyBkZWNpc2lvbiwgbm90IGRpc3RhbmNlIChNdW1iYWkgaXMgbmVhcmVyKQogICAgICAgICAgcmV0dXJuICd1c2EnOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvLyBFVSwgQUYsIEFOIC0+IGtlZXAgQ3lwcnVzIGRlZmF1bHQKICAgICAgICAgIHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIEdFTyBQUkUtU0VMRUNUSU9OIChwaWNrZXIgdmlzaWJsZSwgZ2VvIG9ubHkgcGlja3MgdGhlIGluaXRpYWwgdGFiKQogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIEZ1bGx5IGNsaWVudC1zaWRlOiB3ZSBsb29rIHVwIHRoZSB2aXNpdG9yJ3MgSVAgdmlhIGlwYXBpLmNvIGFuZCBwcmUtc2VsZWN0IHRoZSBuZWFyZXN0CiAgICAvLyBkYXRhY2VudGVyIGluIHRoZSBwaWNrZXIuIE5vIGJhY2tlbmQvY29va2llIGludm9sdmVtZW50LiBTdG9jayBuZXZlciBtb3ZlcyB0aGUgc2VsZWN0aW9uIOKAlAogICAgLy8gYSBzb2xkLW91dCByZWdpb24gc3RheXMgc2VsZWN0ZWQgYW5kIHNob3dzIGl0cyBvd24gd2FpdGxpc3QsIGJlY2F1c2Ugc2lsZW50bHkgY2hlY2tpbmcgYQogICAgLy8gY3VzdG9tZXIgb3V0IG9mIGEgZGlmZmVyZW50IGNvbnRpbmVudCBpcyB3b3JzZSB0aGFuIHRlbGxpbmcgdGhlbSB0byB3YWl0IGZvciB0aGlzIG9uZS4KCiAgICAvLyBHZW8tc3VnZ2VzdGVkIGxvY2F0aW9uIChMT0NBVElPTlMga2V5KSwgbnVsbCB1bnRpbCB0aGUgbG9va3VwIHJlc29sdmVzLgogICAgbGV0IGdlb1ByZWZlcnJlZExvY2F0aW9uID0gbnVsbDsKCiAgICAvLyBGbGlwcyB0cnVlIHRoZSBmaXJzdCB0aW1lIHRoZSByZWFsIHBpY2tlciByZXBsYWNlcyBpdHMgc2tlbGV0b24uCiAgICBsZXQgbG9jYXRpb25SZXNvbHZlZCA9IGZhbHNlOwoKICAgIC8vIGlwYXBpLmNvIGlzIGEgdGhpcmQgcGFydHkgdGhhdCBjYW4gYmUgc2xvdywgcmF0ZS1saW1pdGVkICg0MjkpIG9yIGJsb2NrZWQgYnkgYW4gZXh0ZW5zaW9uLCBzbyB0aGUKICAgIC8vIHBpY2tlciBwYWludHMgb24gdGhpcyBkZWFkbGluZSByYXRoZXIgdGhhbiB3YWl0aW5nIGZvciBpdCDigJQgb3RoZXJ3aXNlIHRoZSBza2VsZXRvbiBzaGltbWVycyBvbiBsb25nCiAgICAvLyBhZnRlciB0aGUgYXZhaWxhYmlsaXR5IGRhdGEgbGFuZGVkLiBBIHJlc3VsdCBhcnJpdmluZyBsYXRlciBzdGlsbCBwcmUtc2VsZWN0cyAoYXBwbHlHZW9EYXRhY2VudGVyKS4KICAgIGNvbnN0IEdFT19QSUNLRVJfREVBRExJTkVfTVMgPSAxNTAwOwogICAgY29uc3QgR0VPX0xPT0tVUF9USU1FT1VUX01TID0gNzAwMDsKICAgIGNvbnN0IEdFT19TRVNTSU9OX0tFWSA9ICdyYW1fZ2VvX2xvY2F0aW9uJzsKCiAgICAvLyBTd2FwIHRoZSBwaWNrZXIgc2tlbGV0b24gZm9yIHRoZSByZWFsIHRhYnMsIG9uY2UsIHdoYXRldmVyIHRoZSBnZW8gbG9va3VwIGRpZCDigJQgaW5jbHVkaW5nIHRoZQogICAgLy8gcGF0aHMgdGhhdCBiYWlsIGVhcmx5IChub24tT0sgcmVzcG9uc2UsIGVycm9yIHBheWxvYWQsIEN5cHJ1cyBkZWZhdWx0KSBhbmQgdGhlIGZhaWx1cmUgcGF0aC4KICAgIGZ1bmN0aW9uIHNldHRsZUxvY2F0aW9uUGlja2VyKCkgewogICAgICBpZiAobG9jYXRpb25SZXNvbHZlZCkgcmV0dXJuOwogICAgICBsb2NhdGlvblJlc29sdmVkID0gdHJ1ZTsKICAgICAgcmVuZGVyTG9jYXRpb25UYWJzKCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVhZENhY2hlZEdlb0xvY2F0aW9uKCkgewogICAgICB0cnkgewogICAgICAgIGNvbnN0IGNhY2hlZCA9IHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKEdFT19TRVNTSU9OX0tFWSk7CiAgICAgICAgcmV0dXJuIExPQ0FUSU9OU1tjYWNoZWRdID8gY2FjaGVkIDogbnVsbDsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY2FjaGVHZW9Mb2NhdGlvbihsb2NhdGlvbktleSkgewogICAgICB0cnkgewogICAgICAgIHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKEdFT19TRVNTSU9OX0tFWSwgbG9jYXRpb25LZXkpOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgLy8gUHJpdmF0ZSBtb2RlOiB0aGUgbG9va3VwIGp1c3QgcnVucyBhZ2FpbiBvbiB0aGUgbmV4dCBwYWdlIHZpZXcuCiAgICAgIH0KICAgIH0KCiAgICAvLyBSZXNvbHZlIHRoZSBuZWFyZXN0IGRhdGFjZW50ZXIgZnJvbSB0aGUgdmlzaXRvcidzIElQIChjb250aW5lbnQpLCB0aGVuIGFwcGx5IGl0LgogICAgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUdlb1ByZWZlcnJlZExvY2F0aW9uKCkgewogICAgICAvLyBDYWNoZWQgaGl0IHBhaW50cyB0aGUgcmlnaHQgdGFiIHN5bmNocm9ub3VzbHksIGJlZm9yZSB0aGUgc2tlbGV0b24gaXMgZXZlciBhbmltYXRlZC4KICAgICAgY29uc3QgY2FjaGVkID0gcmVhZENhY2hlZEdlb0xvY2F0aW9uKCk7CiAgICAgIGlmIChjYWNoZWQpIHsKICAgICAgICBnZW9QcmVmZXJyZWRMb2NhdGlvbiA9IGNhY2hlZDsKICAgICAgICBhcHBseUdlb0RhdGFjZW50ZXIoKTsKICAgICAgICBzZXR0bGVMb2NhdGlvblBpY2tlcigpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgdHJ5IHsKICAgICAgICAvLyBpcGFwaS5jbyBzdXBwb3J0cyBDT1JTIG9uIHRoZSBmcmVlIHRpZXIgYW5kIHJldHVybnMgYGNvdW50cnlfY29kZWAgKyBgY29udGluZW50X2NvZGVgLgogICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vaXBhcGkuY28vanNvbi8nLCB7IHNpZ25hbDogQWJvcnRTaWduYWwudGltZW91dChHRU9fTE9PS1VQX1RJTUVPVVRfTVMpIH0pOwogICAgICAgIGlmICghcmVzcG9uc2Uub2spIHJldHVybjsKCiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTsKICAgICAgICBpZiAoIWRhdGEgfHwgZGF0YS5lcnJvcikgcmV0dXJuOwoKICAgICAgICBjb25zdCBkZXRlY3RlZCA9IGdlb1RvTG9jYXRpb24oZGF0YS5jb3VudHJ5X2NvZGUsIGRhdGEuY29udGluZW50X2NvZGUpOwogICAgICAgIGlmICghZGV0ZWN0ZWQpIHsKICAgICAgICAgIGNhY2hlR2VvTG9jYXRpb24oJ2N5cHJ1cycpOyAvLyBFVS9BRiArIE5lYXItRWFzdC9DYXVjYXN1cyBrZWVwIHRoZSBDeXBydXMgZGVmYXVsdAogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZ2VvUHJlZmVycmVkTG9jYXRpb24gPSBkZXRlY3RlZDsKICAgICAgICBjYWNoZUdlb0xvY2F0aW9uKGRldGVjdGVkKTsKICAgICAgICBhcHBseUdlb0RhdGFjZW50ZXIoKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIC8vIFNpbGVudCBmYWlsIC0gdGhlIHBhZ2UgYWxyZWFkeSBzaG93cyB0aGUgQ3lwcnVzIGRlZmF1bHQsIHdoaWNoIGlzIGZpbmUuCiAgICAgICAgY29uc29sZS53YXJuKCdMb2NhdGlvbiBhdXRvLWRldGVjdCBmYWlsZWQ7IGtlZXBpbmcgZGVmYXVsdC4nLCBlKTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICBzZXR0bGVMb2NhdGlvblBpY2tlcigpOwogICAgICB9CiAgICB9CgogICAgLy8gVG90YWwgZGV2aWNlcyBhdmFpbGFibGUgaW4gYSBkYXRhY2VudGVyIGFjcm9zcyBhbGwgc3RvcmFnZSB0aWVycyAobnVsbCB3aGVuIHVua25vd24pLgogICAgZnVuY3Rpb24gdG90YWxBdmFpbGFibGVGb3JMb2NhdGlvbihsb2NhdGlvbktleSkgewogICAgICBjb25zdCBiYWNrZW5kS2V5ID0gTE9DQVRJT05TW2xvY2F0aW9uS2V5XT8uYmFja2VuZEtleTsKICAgICAgY29uc3QgZGMgPSBsYXN0QXZhaWxhYmlsaXR5UGF5bG9hZD8uZGF0YWNlbnRlcnM\/LmZpbmQoZCA9PiBkLmxvY2F0aW9uID09PSBiYWNrZW5kS2V5KTsKICAgICAgaWYgKCFkYykgcmV0dXJuIG51bGw7CiAgICAgIHJldHVybiBOdW1iZXIoZGMuYXZhaWxhYmxlRGV2aWNlcyA\/PyAwKQogICAgICAgICsgTnVtYmVyKGRjLmF2YWlsYWJsZURldmljZXNXaXRoMjU2R2JEcml2ZSA\/PyAwKQogICAgICAgICsgTnVtYmVyKGRjLmF2YWlsYWJsZURldmljZXNXaXRoNTEyR2JEcml2ZSA\/PyAwKTsKICAgIH0KCiAgICAvLyBQcmUtc2VsZWN0IHRoZSBnZW8tc3VnZ2VzdGVkIGRhdGFjZW50ZXIuIFJ1bnMgb25jZSB0aGUgSVAgbG9va3VwIHJlc29sdmVzIGFuZCBuZXZlciBhZ2FpbgogICAgLy8gYWZ0ZXIgdGhlIHZpc2l0b3IgdG91Y2hlcyBhIHRhYi4gUGFpbnRpbmcgdGhlIHBpY2tlciBpcyBub3JtYWxseSBzZXR0bGVMb2NhdGlvblBpY2tlcidzIGpvYiwgc28KICAgIC8vIHRoZSBza2VsZXRvbiBpcyByZXBsYWNlZCBleGFjdGx5IG9uY2UsIGFscmVhZHkgc2hvd2luZyB0aGUgcmlnaHQgdGFiIOKAlCB1bmxlc3MgdGhlIGxvb2t1cCBjYW1lCiAgICAvLyBiYWNrIGFmdGVyIEdFT19QSUNLRVJfREVBRExJTkVfTVMsIGluIHdoaWNoIGNhc2UgdGhlIHBpY2tlZCB0YWIgaGFzIHRvIGJlIHJlcGFpbnRlZC4KICAgIGZ1bmN0aW9uIGFwcGx5R2VvRGF0YWNlbnRlcigpIHsKICAgICAgaWYgKHVzZXJJbnRlcmFjdGVkV2l0aExvY2F0aW9uKSByZXR1cm4gdHJ1ZTsgLy8gdGhlIHZpc2l0b3IncyBwaWNrIHdpbnMKCiAgICAgIGNvbnN0IHByZWZlcnJlZCA9IGdlb1ByZWZlcnJlZExvY2F0aW9uOwogICAgICBpZiAoIXByZWZlcnJlZCkgcmV0dXJuIGZhbHNlOwoKICAgICAgY29uc3QgdGFyZ2V0ID0gTE9DQVRJT05TW3ByZWZlcnJlZF0\/LmF2YWlsYWJsZSA\/IHByZWZlcnJlZCA6ICdjeXBydXMnOwogICAgICBpZiAodGFyZ2V0ICE9PSBzZWxlY3RlZExvY2F0aW9uKSB7CiAgICAgICAgc2VsZWN0ZWRMb2NhdGlvbiA9IHRhcmdldDsKICAgICAgICBhcHBseUF2YWlsYWJpbGl0eUZvclNlbGVjdGVkTG9jYXRpb24oKTsKICAgICAgICBpZiAobG9jYXRpb25SZXNvbHZlZCkgcmVuZGVyTG9jYXRpb25UYWJzKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIFBSSUNJTkcgRlVOQ1RJT05TCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICAgIGZ1bmN0aW9uIGdldFN0b3JhZ2VQcmljZShzdG9yYWdlS2V5LCBjeWNsZUtleSkgewogICAgICBjb25zdCBzdG9yYWdlID0gUFJJQ0lOR19DT05GSUcuc3RvcmFnZVtzdG9yYWdlS2V5XTsKICAgICAgaWYgKCFzdG9yYWdlIHx8IHN0b3JhZ2UucHJpY2UgPT09IDApIHJldHVybiAwOwoKICAgICAgLy8gRm9yIHdlZWtseSBhbmQgbW9udGhseSwgdXNlIHRoZSBtb250aGx5IHByaWNlCiAgICAgIGlmIChjeWNsZUtleSA9PT0gJ3dlZWtseScgfHwgY3ljbGVLZXkgPT09ICdtb250aGx5JykgewogICAgICAgIHJldHVybiBzdG9yYWdlLm1vbnRobHlQcmljZTsKICAgICAgfQoKICAgICAgLy8gRm9yIDMgbW9udGhzCiAgICAgIGlmIChjeWNsZUtleSA9PT0gJzNtb250aCcpIHsKICAgICAgICByZXR1cm4gc3RvcmFnZS5tb250aGx5UHJpY2UgKiAoc3RvcmFnZVsnM21vbnRoTXVsdGlwbGllciddIHx8IDMpOwogICAgICB9CgogICAgICAvLyBGb3IgNiBtb250aHMKICAgICAgaWYgKGN5Y2xlS2V5ID09PSAnNm1vbnRoJykgewogICAgICAgIHJldHVybiBzdG9yYWdlLm1vbnRobHlQcmljZSAqIChzdG9yYWdlWyc2bW9udGhNdWx0aXBsaWVyJ10gfHwgNik7CiAgICAgIH0KCiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGNhbGN1bGF0ZVRvdGFsKCkgewogICAgICBjb25zdCBjeWNsZSA9IFBSSUNJTkdfQ09ORklHLmN5Y2xlc1tzZWxlY3RlZEN5Y2xlXTsKICAgICAgY29uc3QgYmFzZVByaWNlID0gY3ljbGUuYmFzZVByaWNlOwogICAgICBjb25zdCBzdG9yYWdlUHJpY2UgPSBnZXRTdG9yYWdlUHJpY2Uoc2VsZWN0ZWRTdG9yYWdlLCBzZWxlY3RlZEN5Y2xlKTsKICAgICAgcmV0dXJuIGJhc2VQcmljZSArIHN0b3JhZ2VQcmljZTsKICAgIH0KCiAgICBmdW5jdGlvbiBmb3JtYXRQcmljZShwcmljZSkgewogICAgICBpZiAocHJpY2UgJSAxID09PSAwKSB7CiAgICAgICAgcmV0dXJuIGAkJHtwcmljZX1gOwogICAgICB9CiAgICAgIHJldHVybiBgJCR7cHJpY2UudG9GaXhlZCgyKX1gOwogICAgfQoKICAgIC8vIFRvdGFsIHBoeXNpY2FsIGRldmljZXMgaW4gdGhlICpzZWxlY3RlZCogZGF0YWNlbnRlciAoYmFzZSArIGl0cyBvd24gZHJpdmUtZXF1aXBwZWQgdW5pdHMpLAogICAgLy8gdXNlZCBmb3IgdGhlIGRhaWx5LXBsYW4gZ2F0ZS4gUmVhZHMgdGhlIHNlbGVjdGVkIERDJ3Mgb3duIGNvdW50cyBzdHJhaWdodCBmcm9tIHRoZSBwYXlsb2FkLAogICAgLy8gZmFsbGluZyBiYWNrIHRvIHRoZSBnbG9iYWxzICh3aGljaCBhcmUgYWxzbyBzZWxlY3RlZC1EQyBzb3VyY2VkKSBiZWZvcmUgdGhlIHBheWxvYWQgbGFuZHMuCiAgICBmdW5jdGlvbiBnZXRUb3RhbEF2YWlsYWJsZURldmljZXMoKSB7CiAgICAgIGNvbnN0IHRvdGFsID0gdG90YWxBdmFpbGFibGVGb3JMb2NhdGlvbihzZWxlY3RlZExvY2F0aW9uKTsKICAgICAgcmV0dXJuIHRvdGFsID8\/IChjdXJyZW50QXZhaWxhYmxlRGV2aWNlcyArIGF2YWlsYWJsZURldmljZXNXaXRoMjU2R2JEcml2ZSArIGF2YWlsYWJsZURldmljZXNXaXRoNTEyR2JEcml2ZSk7CiAgICB9CgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIENST1NTLUxPQ0FUSU9OIEFWQUlMQUJJTElUWSBOT1RJQ0VTCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gV2hlbiB3aGF0IHRoZSB2aXNpdG9yIHdhbnRzIGlzIHNvbGQgb3V0IGluIHRoZSBzZWxlY3RlZCBkYXRhY2VudGVyIGJ1dCBhbm90aGVyIG9uZSBoYXMgaXQsCiAgICAvLyBzYXkgc28gYW5kIG9mZmVyIGEgb25lLWNsaWNrIHN3aXRjaC4gU3RvY2sgbmV2ZXIgbW92ZXMgdGhlIHNlbGVjdGlvbiBvbiBpdHMgb3duIChzZWUgdGhlIGdlbwogICAgLy8gc2VjdGlvbik6IGV2ZXJ5IGp1bXAgdG8gYW5vdGhlciByZWdpb24gaXMgYW4gZXhwbGljaXQgdGFwIG9uIG9uZSBvZiB0aGVzZSBsaW5rcy4KICAgIC8vIEV2ZXJ5dGhpbmcgaGVyZSBpcyBkZXJpdmVkIGZyb20gdGhlIGNhY2hlZCBzdGF0dXMgcGF5bG9hZCwgc28gbm90aGluZyByZW5kZXJzIHVudGlsIGl0IGxhbmRzLgoKICAgIC8vIFRydWUgZnJvbSB0aGUgbW9tZW50IHRoZSB2aXNpdG9yIHRhcHMgdGhlIHNvbGQtb3V0IERhaWx5IHRhYiB1bnRpbCB0aGUgbG9jYXRpb24gY2hhbmdlcy4KICAgIC8vIFRoZSBEYWlseSBub3RpY2UgaXMgZGVsaWJlcmF0ZWx5IE5PVCBzaG93biB1cCBmcm9udDogaXQgb25seSBhbnN3ZXJzIHRoZSB0YXAuCiAgICBsZXQgZGFpbHlOb3RpY2VSZXF1ZXN0ZWQgPSBmYWxzZTsKCiAgICBmdW5jdGlvbiBkYXRhY2VudGVyRm9yKGxvY2F0aW9uS2V5KSB7CiAgICAgIGNvbnN0IGJhY2tlbmRLZXkgPSBMT0NBVElPTlNbbG9jYXRpb25LZXldPy5iYWNrZW5kS2V5OwogICAgICByZXR1cm4gbGFzdEF2YWlsYWJpbGl0eVBheWxvYWQ\/LmRhdGFjZW50ZXJzPy5maW5kKGQgPT4gZC5sb2NhdGlvbiA9PT0gYmFja2VuZEtleSkgPz8gbnVsbDsKICAgIH0KCiAgICAvLyBEb2VzIHRoaXMgZGF0YWNlbnRlciBoYXZlIGB3aGF0YCBpbiBzdG9jayByaWdodCBub3c\/CiAgICAvLyAgICdhbnknICAgICAgLT4gYXQgbGVhc3Qgb25lIHBoeXNpY2FsIE1hYyAoYmFzZSBvciBkcml2ZS1lcXVpcHBlZCkKICAgIC8vICAgJ2RhaWx5JyAgICAtPiBlbm91Z2ggTWFjcyB0byBwYXNzIHRoYXQgREMncyBvd24gZGFpbHktcGxhbiB0aHJlc2hvbGQKICAgIC8vICAgJ2Jhc2UnIHwgJ2FkZG9uMjU2JyB8ICdhZGRvbjUxMicgLT4gdGhhdCBzcGVjaWZpYyBjb25maWd1cmF0aW9uCiAgICBmdW5jdGlvbiBsb2NhdGlvbkhhcyhsb2NhdGlvbktleSwgd2hhdCkgewogICAgICBjb25zdCBkYyA9IGRhdGFjZW50ZXJGb3IobG9jYXRpb25LZXkpOwogICAgICBpZiAoIWRjKSByZXR1cm4gZmFsc2U7CiAgICAgIHN3aXRjaCAod2hhdCkgewogICAgICAgIGNhc2UgJ2RhaWx5JzoKICAgICAgICAgIHJldHVybiAodG90YWxBdmFpbGFibGVGb3JMb2NhdGlvbihsb2NhdGlvbktleSkgPz8gMCkgPiBOdW1iZXIoZGMuZGFpbHlQbGFuQXZhaWxhYmlsaXR5VGhyZXNob2xkID8\/IDMpOwogICAgICAgIGNhc2UgJ2Jhc2UnOgogICAgICAgICAgcmV0dXJuIE51bWJlcihkYy5hdmFpbGFibGVEZXZpY2VzID8\/IDApID4gMDsKICAgICAgICBjYXNlICdhZGRvbjI1Nic6CiAgICAgICAgICByZXR1cm4gTnVtYmVyKGRjLmF2YWlsYWJsZURldmljZXNXaXRoMjU2R2JEcml2ZSA\/PyAwKSA+IDA7CiAgICAgICAgY2FzZSAnYWRkb241MTInOgogICAgICAgICAgcmV0dXJuIE51bWJlcihkYy5hdmFpbGFibGVEZXZpY2VzV2l0aDUxMkdiRHJpdmUgPz8gMCkgPiAwOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gKHRvdGFsQXZhaWxhYmxlRm9yTG9jYXRpb24obG9jYXRpb25LZXkpID8\/IDApID4gMDsKICAgICAgfQogICAgfQoKICAgIC8vIEV2ZXJ5IGxvY2F0aW9uIGV4Y2VwdCB0aGUgc2VsZWN0ZWQgb25lLCBDeXBydXMgZmlyc3QgKG1haW4gREMpLCB0aGVuIHBpY2tlciBvcmRlci4KICAgIGZ1bmN0aW9uIG90aGVyTG9jYXRpb25zV2l0aCh3aGF0KSB7CiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhMT0NBVElPTlMpCiAgICAgICAgLmZpbHRlcihrZXkgPT4ga2V5ICE9PSBzZWxlY3RlZExvY2F0aW9uICYmIExPQ0FUSU9OU1trZXldLmF2YWlsYWJsZSAmJiBsb2NhdGlvbkhhcyhrZXksIHdoYXQpKQogICAgICAgIC5zb3J0KChhLCBiKSA9PiAoYSA9PT0gJ2N5cHJ1cycgPyAtMSA6IGIgPT09ICdjeXBydXMnID8gMSA6IDApKTsKICAgIH0KCiAgICBmdW5jdGlvbiBub3RpY2VzUmVhZHkoKSB7CiAgICAgIHJldHVybiBhdmFpbGFiaWxpdHlTdGF0dXNTZXR0bGVkICYmICEhbGFzdEF2YWlsYWJpbGl0eVBheWxvYWQgJiYgISFkYXRhY2VudGVyRm9yKHNlbGVjdGVkTG9jYXRpb24pOwogICAgfQoKICAgIC8vIFJlZ2lvbiBuYW1lIGZvciBub3RpY2UgY29weSwgd2l0aCBub24tYnJlYWtpbmcgc3BhY2VzIHNvICJVU0EgwrcgVGV4YXMiIG5ldmVyIHdyYXBzIG1pZC1uYW1lLgogICAgZnVuY3Rpb24gcmVnaW9uTmFtZShsb2NhdGlvbktleSkgewogICAgICByZXR1cm4gKExPQ0FUSU9OU1tsb2NhdGlvbktleV0\/LmNvdW50cnkgPz8gJ3RoaXMgcmVnaW9uJykucmVwbGFjZSgvIC9nLCAnXHUwMGEwJyk7CiAgICB9CgogICAgZnVuY3Rpb24gc2VsZWN0ZWRMb2NhdGlvbk5hbWUoKSB7CiAgICAgIHJldHVybiByZWdpb25OYW1lKHNlbGVjdGVkTG9jYXRpb24pOwogICAgfQoKICAgIC8vICJDeXBydXMiIC8gIkN5cHJ1cyBhbmQgSW5kaWEiIC8gIkN5cHJ1cywgSW5kaWEgYW5kIFVTQSDCtyBUZXhhcyIsIGVhY2ggbmFtZSBhIHN3aXRjaCBsaW5rLgogICAgZnVuY3Rpb24gbG9jYXRpb25MaW5rcyhrZXlzLCBjeWNsZUtleSkgewogICAgICBjb25zdCBsaW5rcyA9IGtleXMubWFwKGtleSA9PiB7CiAgICAgICAgY29uc3QgY3ljbGVBdHRyID0gY3ljbGVLZXkgPyBgIGRhdGEtYWx0LWN5Y2xlPSIke2N5Y2xlS2V5fSJgIDogJyc7CiAgICAgICAgcmV0dXJuIGA8YSBocmVmPSIjIiBkYXRhLWFsdC1sb2NhdGlvbj0iJHtrZXl9IiR7Y3ljbGVBdHRyfT4ke3JlZ2lvbk5hbWUoa2V5KX08L2E+YDsKICAgICAgfSk7CiAgICAgIGlmIChsaW5rcy5sZW5ndGggPD0gMSkgcmV0dXJuIGxpbmtzLmpvaW4oJycpOwogICAgICByZXR1cm4gbGlua3Muc2xpY2UoMCwgLTEpLmpvaW4oJywgJykgKyAnIGFuZCAnICsgbGlua3NbbGlua3MubGVuZ3RoIC0gMV07CiAgICB9CgogICAgZnVuY3Rpb24gbG9jYXRpb25OYW1lcyhrZXlzKSB7CiAgICAgIGNvbnN0IG5hbWVzID0ga2V5cy5tYXAoa2V5ID0+IHJlZ2lvbk5hbWUoa2V5KSk7CiAgICAgIGlmIChuYW1lcy5sZW5ndGggPD0gMSkgcmV0dXJuIG5hbWVzLmpvaW4oJycpOwogICAgICByZXR1cm4gbmFtZXMuc2xpY2UoMCwgLTEpLmpvaW4oJywgJykgKyAnIGFuZCAnICsgbmFtZXNbbmFtZXMubGVuZ3RoIC0gMV07CiAgICB9CgogICAgY29uc3QgTk9USUNFX0lORk9fSUNPTiA9ICc8c3ZnIGNsYXNzPSJhdmFpbGFiaWxpdHktbm90ZV9faWNvbiIgdmlld0JveD0iMCAwIDE2IDE2IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIxLjUiIGFyaWEtaGlkZGVuPSJ0cnVlIj48Y2lyY2xlIGN4PSI4IiBjeT0iOCIgcj0iNi41Ii8+PHBhdGggZD0iTTggNy4ydjQiLz48Y2lyY2xlIGN4PSI4IiBjeT0iNSIgcj0iLjYiIGZpbGw9ImN1cnJlbnRDb2xvciIgc3Ryb2tlPSJub25lIi8+PC9zdmc+JzsKICAgIGNvbnN0IE5PVElDRV9XQVJOX0lDT04gPSAnPHN2ZyBjbGFzcz0iYXZhaWxhYmlsaXR5LW5vdGVfX2ljb24iIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PHBhdGggZD0iTTggMi4yIDE0LjMgMTNIMS43eiIvPjxwYXRoIGQ9Ik04IDYuNXYzLjIiLz48Y2lyY2xlIGN4PSI4IiBjeT0iMTEuNiIgcj0iLjYiIGZpbGw9ImN1cnJlbnRDb2xvciIgc3Ryb2tlPSJub25lIi8+PC9zdmc+JzsKCiAgICAvLyBDcmVhdGUtb3ItcmV1c2UgYSBub3RpY2UgZWxlbWVudCByaWdodCBhZnRlciBgYW5jaG9yYDsgaGlkZGVuIGJ5IGRlZmF1bHQuCiAgICBmdW5jdGlvbiBlbnN1cmVOb3RpY2VFbGVtZW50KGlkLCBhbmNob3IsIGNsYXNzTmFtZSkgewogICAgICBsZXQgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7CiAgICAgIGlmICghZWwpIHsKICAgICAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIGVsLmlkID0gaWQ7CiAgICAgICAgZWwuY2xhc3NOYW1lID0gY2xhc3NOYW1lOwogICAgICAgIGVsLmhpZGRlbiA9IHRydWU7CiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVOb3RpY2VDbGljayk7CiAgICAgICAgYW5jaG9yLmluc2VydEFkamFjZW50RWxlbWVudCgnYWZ0ZXJlbmQnLCBlbCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGVsOwogICAgfQoKICAgIGZ1bmN0aW9uIGhhbmRsZU5vdGljZUNsaWNrKGV2ZW50KSB7CiAgICAgIGNvbnN0IGxpbmsgPSBldmVudC50YXJnZXQuY2xvc2VzdCgnYVtkYXRhLWFsdC1sb2NhdGlvbl0sIGFbZGF0YS1vcGVuLXdhaXRsaXN0XScpOwogICAgICBpZiAoIWxpbmspIHJldHVybjsKICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgaWYgKGxpbmsuZGF0YXNldC5hbHRMb2NhdGlvbikgewogICAgICAgIHN3aXRjaFRvTG9jYXRpb24obGluay5kYXRhc2V0LmFsdExvY2F0aW9uLCBsaW5rLmRhdGFzZXQuYWx0Q3ljbGUgfHwgbnVsbCk7CiAgICAgIH0gZWxzZSBpZiAobGluay5kYXRhc2V0Lm9wZW5XYWl0bGlzdCA9PT0gJ2RhaWx5JykgewogICAgICAgIG9wZW5BdmFpbGFiaWxpdHlEaWFsb2coQXZhaWxhYmlsaXR5Tm90aWZpY2F0aW9uVHlwZS5EYWlseSk7CiAgICAgIH0KICAgIH0KCiAgICAvLyBFeHBsaWNpdCwgdmlzaXRvci1pbml0aWF0ZWQganVtcCB0byBhbm90aGVyIHJlZ2lvbiAob3B0aW9uYWxseSBsYW5kaW5nIG9uIGEgZ2l2ZW4gY3ljbGUpLgogICAgZnVuY3Rpb24gc3dpdGNoVG9Mb2NhdGlvbihsb2NhdGlvbktleSwgY3ljbGVLZXkpIHsKICAgICAgaWYgKCFMT0NBVElPTlNbbG9jYXRpb25LZXldKSByZXR1cm47CiAgICAgIHVzZXJJbnRlcmFjdGVkV2l0aExvY2F0aW9uID0gdHJ1ZTsKICAgICAgZGFpbHlOb3RpY2VSZXF1ZXN0ZWQgPSBmYWxzZTsKICAgICAgc2VsZWN0TG9jYXRpb24obG9jYXRpb25LZXkpOwogICAgICBpZiAoY3ljbGVLZXkgJiYgUFJJQ0lOR19DT05GSUcuY3ljbGVzW2N5Y2xlS2V5XSkgewogICAgICAgIHNlbGVjdEN5Y2xlKGN5Y2xlS2V5KTsKICAgICAgfQogICAgICAvLyBUaGUgbGlua3MgbGl2ZSBiZWxvdyB0aGUgcGlja2VyOyBicmluZyBpdCBiYWNrIGludG8gdmlldyBvbmx5IGlmIGl0IHNjcm9sbGVkIGF3YXkuCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2NhdGlvblRhYnMnKT8uc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcsIGJsb2NrOiAnbmVhcmVzdCcgfSk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVuZGVyQXZhaWxhYmlsaXR5Tm90aWNlcygpIHsKICAgICAgY29uc3QgbG9jYXRpb25UYWJzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xvY2F0aW9uVGFicycpOwogICAgICBjb25zdCBjeWNsZVRhYnMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY3ljbGVUYWJzJyk7CiAgICAgIGNvbnN0IGN0YUJ1dHRvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjdGFCdXR0b24nKTsKICAgICAgaWYgKCFsb2NhdGlvblRhYnMgfHwgIWN5Y2xlVGFicyB8fCAhY3RhQnV0dG9uKSByZXR1cm47CgogICAgICBjb25zdCBsb2NhdGlvbk5vdGUgPSBlbnN1cmVOb3RpY2VFbGVtZW50KCdsb2NhdGlvbkF2YWlsYWJpbGl0eU5vdGUnLCBsb2NhdGlvblRhYnMsICdhdmFpbGFiaWxpdHktbm90ZSBpcy13YXJuaW5nJyk7CiAgICAgIGNvbnN0IGRhaWx5Tm90ZSA9IGVuc3VyZU5vdGljZUVsZW1lbnQoJ2RhaWx5QXZhaWxhYmlsaXR5Tm90ZScsIGN5Y2xlVGFicywgJ2F2YWlsYWJpbGl0eS1ub3RlJyk7CiAgICAgIGNvbnN0IGN0YUFsdCA9IGVuc3VyZU5vdGljZUVsZW1lbnQoJ2N0YUFsdExvY2F0aW9uJywgY3RhQnV0dG9uLCAnY3RhLWFsdC1sb2NhdGlvbicpOwoKICAgICAgY29uc3QgcmVhZHkgPSBub3RpY2VzUmVhZHkoKTsKICAgICAgY29uc3QgaGVyZSA9IHNlbGVjdGVkTG9jYXRpb25OYW1lKCk7CiAgICAgIGNvbnN0IHNvbGRPdXRIZXJlID0gcmVhZHkgJiYgIWxvY2F0aW9uSGFzKHNlbGVjdGVkTG9jYXRpb24sICdhbnknKTsKICAgICAgY29uc3Qgc3RvY2tFbHNld2hlcmUgPSByZWFkeSA\/IG90aGVyTG9jYXRpb25zV2l0aCgnYW55JykgOiBbXTsKCiAgICAgIC8vIDEpIFRoZSB3aG9sZSByZWdpb24gaXMgYWxsb2NhdGVkIC0+IHdhcm5pbmcgdW5kZXIgdGhlIHBpY2tlciArIHNlY29uZGFyeSBsaW5rIHVuZGVyIHRoZSBDVEEuCiAgICAgIGlmIChzb2xkT3V0SGVyZSAmJiBzdG9ja0Vsc2V3aGVyZS5sZW5ndGgpIHsKICAgICAgICBsb2NhdGlvbk5vdGUuaW5uZXJIVE1MID0gYCR7Tk9USUNFX1dBUk5fSUNPTn08c3Bhbj5BbGwgTWFjcyBpbiAke2hlcmV9IGFyZSBjdXJyZW50bHkgYWxsb2NhdGVkLiBgCiAgICAgICAgICArIGBBdmFpbGFibGUgbm93IGluICR7bG9jYXRpb25MaW5rcyhzdG9ja0Vsc2V3aGVyZSl9LCBvciBqb2luIHRoZSAke2hlcmV9IHdhaXRsaXN0IGJlbG93Ljwvc3Bhbj5gOwogICAgICAgIGxvY2F0aW9uTm90ZS5oaWRkZW4gPSBmYWxzZTsKICAgICAgICBjdGFBbHQuaW5uZXJIVE1MID0gYG9yIDxhIGhyZWY9IiMiIGRhdGEtYWx0LWxvY2F0aW9uPSIke3N0b2NrRWxzZXdoZXJlWzBdfSI+Z2V0IGEgTWFjIGluICR7cmVnaW9uTmFtZShzdG9ja0Vsc2V3aGVyZVswXSl9IG5vdzwvYT5gOwogICAgICAgIGN0YUFsdC5oaWRkZW4gPSBmYWxzZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsb2NhdGlvbk5vdGUuaGlkZGVuID0gdHJ1ZTsKICAgICAgICBjdGFBbHQuaGlkZGVuID0gdHJ1ZTsKICAgICAgfQoKICAgICAgLy8gMikgRGFpbHkgc29sZCBvdXQgaGVyZSBidXQgb3BlbiBlbHNld2hlcmUgLT4gaW5mbyB1bmRlciB0aGUgY3ljbGUgdGFicywgb25seSBvbmNlIHRhcHBlZC4KICAgICAgY29uc3QgZGFpbHlPdXRIZXJlID0gcmVhZHkgJiYgIWxvY2F0aW9uSGFzKHNlbGVjdGVkTG9jYXRpb24sICdkYWlseScpOwogICAgICBjb25zdCBkYWlseUVsc2V3aGVyZSA9IHJlYWR5ID8gb3RoZXJMb2NhdGlvbnNXaXRoKCdkYWlseScpIDogW107CiAgICAgIGlmIChkYWlseU5vdGljZVJlcXVlc3RlZCAmJiBkYWlseU91dEhlcmUgJiYgIXNvbGRPdXRIZXJlICYmIGRhaWx5RWxzZXdoZXJlLmxlbmd0aCkgewogICAgICAgIGRhaWx5Tm90ZS5pbm5lckhUTUwgPSBgJHtOT1RJQ0VfSU5GT19JQ09OfTxzcGFuPkRhaWx5IHBsYW4gaXMgc29sZCBvdXQgaW4gJHtoZXJlfS4gYAogICAgICAgICAgKyBgQXZhaWxhYmxlIG5vdyBpbiAke2xvY2F0aW9uTGlua3MoZGFpbHlFbHNld2hlcmUsICdkYWlseScpfSwgb3IgPGEgaHJlZj0iIyIgZGF0YS1vcGVuLXdhaXRsaXN0PSJkYWlseSI+am9pbiB0aGUgd2FpdGxpc3Q8L2E+Ljwvc3Bhbj5gOwogICAgICAgIGRhaWx5Tm90ZS5oaWRkZW4gPSBmYWxzZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkYWlseU5vdGUuaGlkZGVuID0gdHJ1ZTsKICAgICAgfQogICAgfQoKICAgIC8vIEluc2lkZSB0aGUgd2FpdGxpc3QgZGlhbG9nOiAiUHJlZmVyIG5vdCB0byB3YWl0PyIgcm93IHdpdGggb25lIHN3aXRjaCBidXR0b24gcGVyIHJlZ2lvbgogICAgLy8gdGhhdCBoYXMgd2hhdCB0aGUgdmlzaXRvciBhc2tlZCBmb3IuIGB3aGF0YCBtaXJyb3JzIGxvY2F0aW9uSGFzKCkuCiAgICBmdW5jdGlvbiByZW5kZXJEaWFsb2dBbHRlcm5hdGl2ZSh3aGF0LCBjeWNsZUtleSkgewogICAgICBpZiAoIWF2YWlsYWJpbGl0eURpYWxvZyB8fCAhYXZhaWxhYmlsaXR5Rm9ybSkgcmV0dXJuOwogICAgICBsZXQgcm93ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2F2YWlsYWJpbGl0eUFsdExvY2F0aW9uJyk7CiAgICAgIGlmICghcm93KSB7CiAgICAgICAgcm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICAgICAgcm93LmlkID0gJ2F2YWlsYWJpbGl0eUFsdExvY2F0aW9uJzsKICAgICAgICByb3cuY2xhc3NOYW1lID0gJ2F2YWlsYWJpbGl0eS1hbHQnOwogICAgICAgIHJvdy5oaWRkZW4gPSB0cnVlOwogICAgICAgIGF2YWlsYWJpbGl0eUZvcm0uaW5zZXJ0QWRqYWNlbnRFbGVtZW50KCdiZWZvcmViZWdpbicsIHJvdyk7CiAgICAgICAgcm93LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7CiAgICAgICAgICBjb25zdCBidXR0b24gPSBldmVudC50YXJnZXQuY2xvc2VzdCgnYnV0dG9uW2RhdGEtYWx0LWxvY2F0aW9uXScpOwogICAgICAgICAgaWYgKCFidXR0b24pIHJldHVybjsKICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGJ1dHRvbi5kYXRhc2V0LmFsdExvY2F0aW9uOwogICAgICAgICAgY29uc3QgY3ljbGUgPSBidXR0b24uZGF0YXNldC5hbHRDeWNsZSB8fCBudWxsOwogICAgICAgICAgY2xvc2VBdmFpbGFiaWxpdHlEaWFsb2coKTsKICAgICAgICAgIHN3aXRjaFRvTG9jYXRpb24odGFyZ2V0LCBjeWNsZSk7CiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIGNvbnN0IGFsdGVybmF0aXZlcyA9IG5vdGljZXNSZWFkeSgpID8gb3RoZXJMb2NhdGlvbnNXaXRoKHdoYXQpIDogW107CiAgICAgIGlmICghYWx0ZXJuYXRpdmVzLmxlbmd0aCkgewogICAgICAgIHJvdy5oaWRkZW4gPSB0cnVlOwogICAgICAgIHJvdy5pbm5lckhUTUwgPSAnJzsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIGNvbnN0IHN1YmplY3QgPSB3aGF0ID09PSAnZGFpbHknID8gJ1RoZSBkYWlseSBwbGFuIGlzJwogICAgICAgIDogKHdoYXQgPT09ICdhZGRvbjI1NicgfHwgd2hhdCA9PT0gJ2FkZG9uNTEyJykgPyAnVGhpcyBjb25maWd1cmF0aW9uIGlzJwogICAgICAgIDogJ01hY3MgYXJlJzsKICAgICAgY29uc3QgYnV0dG9ucyA9IGFsdGVybmF0aXZlcy5tYXAoa2V5ID0+IHsKICAgICAgICBjb25zdCBjeWNsZUF0dHIgPSBjeWNsZUtleSA\/IGAgZGF0YS1hbHQtY3ljbGU9IiR7Y3ljbGVLZXl9ImAgOiAnJzsKICAgICAgICByZXR1cm4gYDxidXR0b24gdHlwZT0iYnV0dG9uIiBkYXRhLWFsdC1sb2NhdGlvbj0iJHtrZXl9IiR7Y3ljbGVBdHRyfT5Td2l0Y2ggdG8gJHtyZWdpb25OYW1lKGtleSl9PC9idXR0b24+YDsKICAgICAgfSkuam9pbignJyk7CiAgICAgIHJvdy5pbm5lckhUTUwgPSBgPHNwYW4+UHJlZmVyIG5vdCB0byB3YWl0PyAke3N1YmplY3R9IGF2YWlsYWJsZSBub3cgaW4gJHtsb2NhdGlvbk5hbWVzKGFsdGVybmF0aXZlcyl9Ljwvc3Bhbj48ZGl2IGNsYXNzPSJhdmFpbGFiaWxpdHktYWx0X19hY3Rpb25zIj4ke2J1dHRvbnN9PC9kaXY+YDsKICAgICAgcm93LmhpZGRlbiA9IGZhbHNlOwogICAgfQoKICAgIC8vIFNrZWxldG9uIHBsYWNlaG9sZGVycyBzaG93biB1bnRpbCBhdmFpbGFiaWxpdHkgZGF0YSBhcnJpdmVzIGFuZCB0aGUgcmVhbAogICAgLy8gY3ljbGUgdGFicyAvIHN0b3JhZ2Ugb3B0aW9ucyBhcmUgcmVuZGVyZWQuCiAgICAvLwogICAgLy8gVGhlIGxvY2F0aW9uIHBpY2tlciBoYXMgaXRzIG93biBza2VsZXRvbiBvbiBhIGRpZmZlcmVudCBzaWduYWw6IGl0IHdhaXRzIG9uIHRoZSBnZW8gbG9va3VwLAogICAgLy8gbm90IG9uIGF2YWlsYWJpbGl0eSwgc28gdGhlIHZpc2l0b3IgbmV2ZXIgc2VlcyBDeXBydXMgaGlnaGxpZ2h0ZWQgZm9yIGEgbW9tZW50IGFuZCB0aGVuCiAgICAvLyB3YXRjaGVzIGl0IGp1bXAgdG8gdGhlaXIgb3duIHJlZ2lvbi4KICAgIGZ1bmN0aW9uIHJlbmRlckxvY2F0aW9uVGFic1NrZWxldG9uKCkgewogICAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbG9jYXRpb25UYWJzJyk7CiAgICAgIGlmICghY29udGFpbmVyKSByZXR1cm47CiAgICAgIGxldCBodG1sID0gJyc7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgT2JqZWN0LmtleXMoTE9DQVRJT05TKS5sZW5ndGg7IGkrKykgewogICAgICAgIGh0bWwgKz0gYAogICAgICAgICAgPGRpdiBjbGFzcz0iY3ljbGUtdGFiIGlzLXNrZWxldG9uIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0ic2tlbGV0b24tYmFyIiBzdHlsZT0iaGVpZ2h0OjE0cHg7d2lkdGg6NTUlO21hcmdpbjo2cHggYXV0byA4cHg7Ij48L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0ic2tlbGV0b24tYmFyIiBzdHlsZT0iaGVpZ2h0OjEwcHg7d2lkdGg6NDAlO21hcmdpbjowIGF1dG87Ij48L2Rpdj4KICAgICAgICAgIDwvZGl2PgogICAgICAgIGA7CiAgICAgIH0KICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7CiAgICB9CgogICAgZnVuY3Rpb24gcmVuZGVyQ3ljbGVUYWJzU2tlbGV0b24oKSB7CiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjeWNsZVRhYnMnKTsKICAgICAgaWYgKCFjb250YWluZXIpIHJldHVybjsKICAgICAgbGV0IGh0bWwgPSAnJzsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA1OyBpKyspIHsKICAgICAgICBodG1sICs9IGAKICAgICAgICAgIDxkaXYgY2xhc3M9ImN5Y2xlLXRhYiBpcy1za2VsZXRvbiI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InNrZWxldG9uLWJhciIgc3R5bGU9ImhlaWdodDoxNHB4O3dpZHRoOjU1JTttYXJnaW46NnB4IGF1dG8gOHB4OyI+PC9kaXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InNrZWxldG9uLWJhciIgc3R5bGU9ImhlaWdodDoxMHB4O3dpZHRoOjQwJTttYXJnaW46MCBhdXRvOyI+PC9kaXY+CiAgICAgICAgICA8L2Rpdj4KICAgICAgICBgOwogICAgICB9CiAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbmRlclN0b3JhZ2VPcHRpb25zU2tlbGV0b24oKSB7CiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdG9yYWdlQ29udGFpbmVyJyk7CiAgICAgIGlmICghY29udGFpbmVyKSByZXR1cm47CiAgICAgIGxldCBvcHRpb25zSHRtbCA9ICcnOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDM7IGkrKykgewogICAgICAgIG9wdGlvbnNIdG1sICs9IGAKICAgICAgICAgIDxkaXYgY2xhc3M9InN0b3JhZ2Utb3B0aW9uIGlzLXNrZWxldG9uIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0ic2tlbGV0b24tYmFyIiBzdHlsZT0iaGVpZ2h0OjE4cHg7d2lkdGg6NDUlO21hcmdpbjowIGF1dG8gOHB4OyI+PC9kaXY+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9InNrZWxldG9uLWJhciIgc3R5bGU9ImhlaWdodDoxMnB4O3dpZHRoOjcwJTttYXJnaW46MCBhdXRvIDhweDsiPjwvZGl2PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJza2VsZXRvbi1iYXIiIHN0eWxlPSJoZWlnaHQ6MTNweDt3aWR0aDozNSU7bWFyZ2luOjAgYXV0bzsiPjwvZGl2PgogICAgICAgICAgPC9kaXY+CiAgICAgICAgYDsKICAgICAgfQogICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9InN0b3JhZ2Utb3B0aW9ucyI+JHtvcHRpb25zSHRtbH08L2Rpdj5gOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbmRlckN5Y2xlVGFicygpIHsKICAgICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2N5Y2xlVGFicycpOwogICAgICBpZiAoIWNvbnRhaW5lcikgewogICAgICAgIGNvbnNvbGUuZXJyb3IoJ1JlbnRhTWFjIFByaWNpbmc6ICNjeWNsZVRhYnMgZWxlbWVudCBub3QgZm91bmQnKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICcnOwoKICAgICAgT2JqZWN0LmVudHJpZXMoUFJJQ0lOR19DT05GSUcuY3ljbGVzKS5mb3JFYWNoKChba2V5LCBjeWNsZV0pID0+IHsKICAgICAgICBjb25zdCB0YWIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgICBjb25zdCBpc0RhaWx5VW5hdmFpbGFibGUgPSBrZXkgPT09ICdkYWlseScgJiYgZ2V0VG90YWxBdmFpbGFibGVEZXZpY2VzKCkgPD0gZGFpbHlQbGFuQXZhaWxhYmlsaXR5VGhyZXNob2xkOwogICAgICAgIHRhYi5jbGFzc05hbWUgPSBgY3ljbGUtdGFiICR7a2V5ID09PSBzZWxlY3RlZEN5Y2xlID8gJ2FjdGl2ZScgOiAnJ30gJHtpc0RhaWx5VW5hdmFpbGFibGUgPyAndW5hdmFpbGFibGUnIDogJyd9YDsKICAgICAgICB0YWIuZGF0YXNldC5jeWNsZSA9IGtleTsKCiAgICAgICAgbGV0IGh0bWwgPSBgCiAgICAgICAgICA8c3BhbiBjbGFzcz0iY3ljbGUtbmFtZSI+JHtjeWNsZS5uYW1lfTwvc3Bhbj4KICAgICAgICAgIDxzcGFuIGNsYXNzPSJjeWNsZS1wcmljZSI+JHtmb3JtYXRQcmljZShjeWNsZS5wcmljZVBlckRheSl9L2RheTwvc3Bhbj4KICAgICAgICBgOwoKICAgICAgICBpZiAoY3ljbGUucG9wdWxhcikgewogICAgICAgICAgaHRtbCArPSBgPHNwYW4gY2xhc3M9InBvcHVsYXItYmFkZ2UiPlBvcHVsYXI8L3NwYW4+YDsKICAgICAgICB9IGVsc2UgaWYgKGN5Y2xlLnNhdmluZ3MpIHsKICAgICAgICAgIGh0bWwgKz0gYDxzcGFuIGNsYXNzPSJzYXZpbmdzLWJhZGdlIj4ke2N5Y2xlLnNhdmluZ3N9PC9zcGFuPmA7CiAgICAgICAgfQoKICAgICAgICB0YWIuaW5uZXJIVE1MID0gaHRtbDsKICAgICAgICBpZiAoaXNEYWlseVVuYXZhaWxhYmxlKSB7CiAgICAgICAgICAvLyBIb3ZlciB0b29sdGlwIChDU1MgcmVhZHMgZGF0YS10aXApOiBuYW1lIHRoZSByZWdpb24sIGFuZCB3aGVyZSBEYWlseSBpcyBvcGVuIGluc3RlYWQuCiAgICAgICAgICBjb25zdCBkYWlseUVsc2V3aGVyZSA9IG5vdGljZXNSZWFkeSgpID8gb3RoZXJMb2NhdGlvbnNXaXRoKCdkYWlseScpIDogW107CiAgICAgICAgICB0YWIuZGF0YXNldC50aXAgPSBkYWlseUVsc2V3aGVyZS5sZW5ndGgKICAgICAgICAgICAgPyBgRGFpbHkgcGxhbiBpcyBzb2xkIG91dCBpbiAke3NlbGVjdGVkTG9jYXRpb25OYW1lKCl9LiBBdmFpbGFibGUgaW4gJHtsb2NhdGlvbk5hbWVzKGRhaWx5RWxzZXdoZXJlKX0uYAogICAgICAgICAgICA6ICdEaXNhYmxlZCB3aGVuIGF2YWlsYWJpbGl0eSBpcyBsb3cuIEpvaW4gdGhlIHdhaXRsaXN0IHRvIGJlIG5vdGlmaWVkLic7CiAgICAgICAgfQogICAgICAgIHRhYi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHsKICAgICAgICAgIGlmIChpc0RhaWx5VW5hdmFpbGFibGUpIHsKICAgICAgICAgICAgLy8gVGhlIHRhcCBpcyB3aGF0IGVhcm5zIHRoZSBpbmxpbmUgbm90aWNlIChpdCBpcyBuZXZlciBzaG93biB1cCBmcm9udCkuCiAgICAgICAgICAgIGRhaWx5Tm90aWNlUmVxdWVzdGVkID0gdHJ1ZTsKICAgICAgICAgICAgcmVuZGVyQXZhaWxhYmlsaXR5Tm90aWNlcygpOwogICAgICAgICAgICBvcGVuQXZhaWxhYmlsaXR5RGlhbG9nKEF2YWlsYWJpbGl0eU5vdGlmaWNhdGlvblR5cGUuRGFpbHkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgICBzZWxlY3RDeWNsZShrZXkpOwogICAgICAgIH0pOwogICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0YWIpOwogICAgICB9KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5kZXJTdG9yYWdlT3B0aW9ucygpIHsKICAgICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0b3JhZ2VDb250YWluZXInKTsKICAgICAgaWYgKCFjb250YWluZXIpIHsKICAgICAgICBjb25zb2xlLmVycm9yKCdSZW50YU1hYyBQcmljaW5nOiAjc3RvcmFnZUNvbnRhaW5lciBlbGVtZW50IG5vdCBmb3VuZCcpOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBjb25zdCBjeWNsZSA9IFBSSUNJTkdfQ09ORklHLmN5Y2xlc1tzZWxlY3RlZEN5Y2xlXTsKICAgICAgY29uc3QgaGFzU3RvcmFnZSA9IGN5Y2xlLmhhc1N0b3JhZ2U7CgogICAgICAvLyBSZXNldCB0byBiYXNlIHN0b3JhZ2UgaWYgY3VycmVudCBjeWNsZSBkb2Vzbid0IHN1cHBvcnQgYWRkb25zCiAgICAgIGlmICghaGFzU3RvcmFnZSAmJiBzZWxlY3RlZFN0b3JhZ2UgIT09ICdiYXNlJykgewogICAgICAgIHNlbGVjdGVkU3RvcmFnZSA9ICdiYXNlJzsKICAgICAgfQoKICAgICAgLy8gQ2hlY2sgaWYgY3VycmVudCBzZWxlY3RlZCBzdG9yYWdlIGlzIHVuYXZhaWxhYmxlCiAgICAgIGNvbnN0IGlzQ3VycmVudFNlbGVjdGlvblVuYXZhaWxhYmxlID0KICAgICAgICAoc2VsZWN0ZWRTdG9yYWdlID09PSAnYmFzZScgJiYgY3VycmVudEF2YWlsYWJsZURldmljZXMgPT09IDApIHx8CiAgICAgICAgKHNlbGVjdGVkU3RvcmFnZSA9PT0gJ2FkZG9uMjU2JyAmJiBhdmFpbGFibGVEZXZpY2VzV2l0aDI1NkdiRHJpdmUgPT09IDApIHx8CiAgICAgICAgKHNlbGVjdGVkU3RvcmFnZSA9PT0gJ2FkZG9uNTEyJyAmJiBhdmFpbGFibGVEZXZpY2VzV2l0aDUxMkdiRHJpdmUgPT09IDApOwoKICAgICAgLy8gQXV0by1zZWxlY3QgZmlyc3QgYXZhaWxhYmxlIHN0b3JhZ2Ugb3B0aW9uIGlmIGN1cnJlbnQgc2VsZWN0aW9uIGlzIHVuYXZhaWxhYmxlCiAgICAgIGlmIChpc0N1cnJlbnRTZWxlY3Rpb25VbmF2YWlsYWJsZSAmJiBoYXNTdG9yYWdlKSB7CiAgICAgICAgaWYgKGN1cnJlbnRBdmFpbGFibGVEZXZpY2VzID4gMCkgewogICAgICAgICAgc2VsZWN0ZWRTdG9yYWdlID0gJ2Jhc2UnOwogICAgICAgIH0gZWxzZSBpZiAoYXZhaWxhYmxlRGV2aWNlc1dpdGgyNTZHYkRyaXZlID4gMCkgewogICAgICAgICAgc2VsZWN0ZWRTdG9yYWdlID0gJ2FkZG9uMjU2JzsKICAgICAgICB9IGVsc2UgaWYgKGF2YWlsYWJsZURldmljZXNXaXRoNTEyR2JEcml2ZSA+IDApIHsKICAgICAgICAgIHNlbGVjdGVkU3RvcmFnZSA9ICdhZGRvbjUxMic7CiAgICAgICAgfQogICAgICAgIC8vIElmIG5vdGhpbmcgaXMgYXZhaWxhYmxlLCBrZWVwIGN1cnJlbnQgc2VsZWN0aW9uICh3aWxsIHNob3cgSm9pbiBXYWl0bGlzdCkKICAgICAgfSBlbHNlIGlmIChpc0N1cnJlbnRTZWxlY3Rpb25VbmF2YWlsYWJsZSAmJiAhaGFzU3RvcmFnZSkgewogICAgICAgIC8vIEZvciBkYWlseSBwbGFuLCBqdXN0IGtlZXAgYmFzZSBldmVuIGlmIHVuYXZhaWxhYmxlCiAgICAgICAgc2VsZWN0ZWRTdG9yYWdlID0gJ2Jhc2UnOwogICAgICB9CgogICAgICBjb25zdCBvcHRpb25zQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICAgIG9wdGlvbnNDb250YWluZXIuY2xhc3NOYW1lID0gJ3N0b3JhZ2Utb3B0aW9ucyc7CiAgICAgIG9wdGlvbnNDb250YWluZXIuaWQgPSAnc3RvcmFnZU9wdGlvbnMnOwoKICAgICAgT2JqZWN0LmVudHJpZXMoUFJJQ0lOR19DT05GSUcuc3RvcmFnZSkuZm9yRWFjaCgoW2tleSwgc3RvcmFnZV0pID0+IHsKICAgICAgICBjb25zdCBpc0FkZG9uID0ga2V5ICE9PSAnYmFzZSc7CiAgICAgICAgY29uc3QgaXNEaXNhYmxlZCA9IGlzQWRkb24gJiYgIWhhc1N0b3JhZ2U7CgogICAgICAgIC8vIENoZWNrIGF2YWlsYWJpbGl0eSBkeW5hbWljYWxseSBiYXNlZCBvbiBBUEkgcmVzcG9uc2UgKGRldmljZXMgd2l0aCBkcml2ZXMgYXR0YWNoZWQpCiAgICAgICAgbGV0IGlzVW5hdmFpbGFibGUgPSBmYWxzZTsKICAgICAgICBpZiAoa2V5ID09PSAnYmFzZScpIHsKICAgICAgICAgIGlzVW5hdmFpbGFibGUgPSBjdXJyZW50QXZhaWxhYmxlRGV2aWNlcyA9PT0gMDsKICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ2FkZG9uMjU2JykgewogICAgICAgICAgaXNVbmF2YWlsYWJsZSA9IGF2YWlsYWJsZURldmljZXNXaXRoMjU2R2JEcml2ZSA9PT0gMDsKICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ2FkZG9uNTEyJykgewogICAgICAgICAgaXNVbmF2YWlsYWJsZSA9IGF2YWlsYWJsZURldmljZXNXaXRoNTEyR2JEcml2ZSA9PT0gMDsKICAgICAgICB9CgogICAgICAgIGNvbnN0IG9wdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIGxldCBjbGFzc2VzID0gJ3N0b3JhZ2Utb3B0aW9uJzsKICAgICAgICBpZiAoa2V5ID09PSBzZWxlY3RlZFN0b3JhZ2UgJiYgIWlzVW5hdmFpbGFibGUpIGNsYXNzZXMgKz0gJyBhY3RpdmUnOwogICAgICAgIGlmIChpc0Rpc2FibGVkKSBjbGFzc2VzICs9ICcgZGlzYWJsZWQnOwogICAgICAgIGVsc2UgaWYgKGlzVW5hdmFpbGFibGUpIGNsYXNzZXMgKz0gJyB1bmF2YWlsYWJsZSc7CiAgICAgICAgb3B0aW9uLmNsYXNzTmFtZSA9IGNsYXNzZXM7CiAgICAgICAgb3B0aW9uLmRhdGFzZXQuc3RvcmFnZSA9IGtleTsKCiAgICAgICAgLy8gRm9yIGRpc2FibGVkL3VuYXZhaWxhYmxlIGFkZG9ucywgc2hvdyBtb250aGx5IHByaWNlIGFzIHJlZmVyZW5jZQogICAgICAgIGxldCBwcmljZSwgcHJpY2VMYWJlbDsKICAgICAgICBpZiAoKGlzRGlzYWJsZWQgfHwgaXNVbmF2YWlsYWJsZSkgJiYgc3RvcmFnZS5tb250aGx5UHJpY2UpIHsKICAgICAgICAgIHByaWNlID0gc3RvcmFnZS5tb250aGx5UHJpY2U7CiAgICAgICAgICBwcmljZUxhYmVsID0gYCske2Zvcm1hdFByaWNlKHByaWNlKX0vbW9gOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwcmljZSA9IGdldFN0b3JhZ2VQcmljZShrZXksIHNlbGVjdGVkQ3ljbGUpOwogICAgICAgICAgcHJpY2VMYWJlbCA9IHByaWNlID09PSAwID8gJ0luY2x1ZGVkJyA6IGArJHtmb3JtYXRQcmljZShwcmljZSl9YDsKICAgICAgICB9CgogICAgICAgIGxldCBjb250ZW50SHRtbCA9IGAKICAgICAgICAgIDxkaXYgY2xhc3M9InN0b3JhZ2Utc2l6ZSI+JHtzdG9yYWdlLnNpemV9IEdCPC9kaXY+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJzdG9yYWdlLWxhYmVsIj4ke3N0b3JhZ2UubGFiZWx9PC9kaXY+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJzdG9yYWdlLXByaWNlIj4ke3ByaWNlTGFiZWx9PC9kaXY+CiAgICAgICAgYDsKCiAgICAgICAgaWYgKHN0b3JhZ2UuaXNEZWZhdWx0KSB7CiAgICAgICAgICBjb250ZW50SHRtbCArPSBgPHNwYW4gY2xhc3M9ImRlZmF1bHQtYmFkZ2UiPkRlZmF1bHQ8L3NwYW4+YDsKICAgICAgICB9CgogICAgICAgIC8vIFdyYXAgY29udGVudCBpbiBhIGRpdiBmb3IgdW5hdmFpbGFibGUvZGlzYWJsZWQgb3B0aW9ucyBzbyBibHVyIGRvZXNuJ3QgYWZmZWN0IHRvb2x0aXAKICAgICAgICBpZiAoaXNVbmF2YWlsYWJsZSB8fCBpc0Rpc2FibGVkKSB7CiAgICAgICAgICBvcHRpb24uaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9InN0b3JhZ2UtY29udGVudCI+JHtjb250ZW50SHRtbH08L2Rpdj5gOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb24uaW5uZXJIVE1MID0gY29udGVudEh0bWw7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNVbmF2YWlsYWJsZSAmJiAhaXNEaXNhYmxlZCkgewogICAgICAgICAgLy8gSG92ZXIgdG9vbHRpcCAoQ1NTIHJlYWRzIGRhdGEtdGlwKTogbmFtZSB0aGUgcmVnaW9uLCBhbmQgd2hlcmUgdGhpcyBkcml2ZSBpcyBvcGVuIGluc3RlYWQuCiAgICAgICAgICBjb25zdCBlbHNld2hlcmUgPSBub3RpY2VzUmVhZHkoKSA\/IG90aGVyTG9jYXRpb25zV2l0aChrZXkpIDogW107CiAgICAgICAgICBvcHRpb24uZGF0YXNldC50aXAgPSBlbHNld2hlcmUubGVuZ3RoCiAgICAgICAgICAgID8gYFNvbGQgb3V0IGluICR7c2VsZWN0ZWRMb2NhdGlvbk5hbWUoKX0uIEF2YWlsYWJsZSBpbiAke2xvY2F0aW9uTmFtZXMoZWxzZXdoZXJlKX0uYAogICAgICAgICAgICA6ICdVbmF2YWlsYWJsZSBkdWUgdG8gaGlnaCBkZW1hbmQuIEpvaW4gdGhlIHdhaXRsaXN0IHRvIGJlIG5vdGlmaWVkLic7CiAgICAgICAgfQoKICAgICAgICAvLyBEaXNhYmxlZCB0aWxlcyBhcmUgdGhlIHdyb25nIGJpbGxpbmcgY3ljbGUsIG5vdCBhIHN0b2NrIHByb2JsZW0sIHNvIHRoZXkgc3RheSBpbmVydC4KICAgICAgICBpZiAoIWlzRGlzYWJsZWQpIHsKICAgICAgICAgIG9wdGlvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHsKICAgICAgICAgICAgaWYgKGlzVW5hdmFpbGFibGUpIHsKICAgICAgICAgICAgICBvcGVuQXZhaWxhYmlsaXR5RGlhbG9nKFNUT1JBR0VfVE9fTk9USUZJQ0FUSU9OX1RZUEVba2V5XSk7CiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNlbGVjdFN0b3JhZ2Uoa2V5KTsKICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgb3B0aW9uc0NvbnRhaW5lci5hcHBlbmRDaGlsZChvcHRpb24pOwogICAgICB9KTsKCiAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSAnJzsKICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKG9wdGlvbnNDb250YWluZXIpOwoKICAgICAgLy8gQWRkIG5vdGUgd2hlbiBzdG9yYWdlIGFkZG9ucyBhcmUgZGlzYWJsZWQKICAgICAgaWYgKCFoYXNTdG9yYWdlKSB7CiAgICAgICAgY29uc3Qgbm90ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgICAgIG5vdGUuY2xhc3NOYW1lID0gJ3N0b3JhZ2UtYWRkb24tZGlzYWJsZWQtbm90ZSc7CiAgICAgICAgbm90ZS50ZXh0Q29udGVudCA9ICdTdG9yYWdlIGFkZC1vbnMgYXJlIG5vdCBhdmFpbGFibGUgZm9yIHRoZSBkYWlseSBwbGFuLiBTZWxlY3QgYSB3ZWVrbHkgb3IgbG9uZ2VyIGJpbGxpbmcgY3ljbGUgdG8gYWRkIGV4dHJhIHN0b3JhZ2UuJzsKICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobm90ZSk7CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiB1cGRhdGVQcmljZURpc3BsYXkoKSB7CiAgICAgIGNvbnN0IHRvdGFsID0gY2FsY3VsYXRlVG90YWwoKTsKICAgICAgY29uc3QgY3ljbGUgPSBQUklDSU5HX0NPTkZJRy5jeWNsZXNbc2VsZWN0ZWRDeWNsZV07CgogICAgICBjb25zdCB0b3RhbFByaWNlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG90YWxQcmljZScpOwogICAgICBjb25zdCBwcmljZUJyZWFrZG93bkVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ByaWNlQnJlYWtkb3duJyk7CiAgICAgIGNvbnN0IGFjY2Vzc0R1cmF0aW9uRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWNjZXNzRHVyYXRpb24nKTsKICAgICAgY29uc3Qgc3RvcmFnZU5vdGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RvcmFnZU5vdGUnKTsKCiAgICAgIGlmICghdG90YWxQcmljZUVsIHx8ICFwcmljZUJyZWFrZG93bkVsKSB7CiAgICAgICAgY29uc29sZS5lcnJvcignUmVudGFNYWMgUHJpY2luZzogUHJpY2UgZGlzcGxheSBlbGVtZW50cyBub3QgZm91bmQnKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIHRvdGFsUHJpY2VFbC50ZXh0Q29udGVudCA9IGZvcm1hdFByaWNlKHRvdGFsKTsKICAgICAgcHJpY2VCcmVha2Rvd25FbC50ZXh0Q29udGVudCA9IGN5Y2xlLmJpbGxpbmdMYWJlbC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGN5Y2xlLmJpbGxpbmdMYWJlbC5zbGljZSgxKTsKICAgICAgaWYgKGFjY2Vzc0R1cmF0aW9uRWwpIGFjY2Vzc0R1cmF0aW9uRWwudGV4dENvbnRlbnQgPSBjeWNsZS5hY2Nlc3NEdXJhdGlvbjsKCiAgICAgIC8vIFN0b3JhZ2Ugbm90ZQogICAgICBpZiAoc3RvcmFnZU5vdGUpIHsKICAgICAgICBpZiAoc2VsZWN0ZWRTdG9yYWdlICE9PSAnYmFzZScpIHsKICAgICAgICAgIGNvbnN0IHN0b3JhZ2VQcmljZSA9IGdldFN0b3JhZ2VQcmljZShzZWxlY3RlZFN0b3JhZ2UsIHNlbGVjdGVkQ3ljbGUpOwogICAgICAgICAgY29uc3Qgc3RvcmFnZSA9IFBSSUNJTkdfQ09ORklHLnN0b3JhZ2Vbc2VsZWN0ZWRTdG9yYWdlXTsKICAgICAgICAgIHN0b3JhZ2VOb3RlLnRleHRDb250ZW50ID0gYEluY2x1ZGVzICR7c3RvcmFnZS5sYWJlbH0gc3RvcmFnZSAoKyR7Zm9ybWF0UHJpY2Uoc3RvcmFnZVByaWNlKX0pYDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3RvcmFnZU5vdGUudGV4dENvbnRlbnQgPSAnJzsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBzZWxlY3RDeWNsZShjeWNsZUtleSkgewogICAgICBzZWxlY3RlZEN5Y2xlID0gY3ljbGVLZXk7CgogICAgICAvLyBSZXNldCBzdG9yYWdlIHRvIGJhc2UgaWYgbmV3IGN5Y2xlIGRvZXNuJ3Qgc3VwcG9ydCBzdG9yYWdlCiAgICAgIGlmICghUFJJQ0lOR19DT05GSUcuY3ljbGVzW2N5Y2xlS2V5XS5oYXNTdG9yYWdlKSB7CiAgICAgICAgc2VsZWN0ZWRTdG9yYWdlID0gJ2Jhc2UnOwogICAgICB9CgogICAgICAvLyBTaG93IFNJUCBjdXN0b21pemF0aW9uIGZlYXR1cmUgb25seSBmb3IgNi1tb250aCBwbGFucwogICAgICBjb25zdCBzaXBGZWF0dXJlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NpcEZlYXR1cmUnKTsKICAgICAgaWYgKHNpcEZlYXR1cmUpIHsKICAgICAgICBzaXBGZWF0dXJlLnN0eWxlLmRpc3BsYXkgPSBjeWNsZUtleSA9PT0gJzZtb250aCcgPyAnJyA6ICdub25lJzsKICAgICAgfQoKICAgICAgcmVuZGVyQ3ljbGVUYWJzKCk7CiAgICAgIHJlbmRlclN0b3JhZ2VPcHRpb25zKCk7CiAgICAgIHVwZGF0ZVByaWNlRGlzcGxheSgpOwogICAgICB1cGRhdGVDdGFCdXR0b25TdGF0ZSgpOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbGVjdFN0b3JhZ2Uoc3RvcmFnZUtleSkgewogICAgICBpZiAoIVBSSUNJTkdfQ09ORklHLmN5Y2xlc1tzZWxlY3RlZEN5Y2xlXS5oYXNTdG9yYWdlKSByZXR1cm47CgogICAgICAvLyBQcmV2ZW50IHNlbGVjdGluZyB1bmF2YWlsYWJsZSBzdG9yYWdlIG9wdGlvbnMgKG5vIGRldmljZXMgd2l0aCB0aGF0IGRyaXZlIGF2YWlsYWJsZSkKICAgICAgaWYgKHN0b3JhZ2VLZXkgPT09ICdhZGRvbjI1NicgJiYgYXZhaWxhYmxlRGV2aWNlc1dpdGgyNTZHYkRyaXZlID09PSAwKSByZXR1cm47CiAgICAgIGlmIChzdG9yYWdlS2V5ID09PSAnYWRkb241MTInICYmIGF2YWlsYWJsZURldmljZXNXaXRoNTEyR2JEcml2ZSA9PT0gMCkgcmV0dXJuOwoKICAgICAgc2VsZWN0ZWRTdG9yYWdlID0gc3RvcmFnZUtleTsKICAgICAgcmVuZGVyU3RvcmFnZU9wdGlvbnMoKTsKICAgICAgdXBkYXRlUHJpY2VEaXNwbGF5KCk7CiAgICAgIHVwZGF0ZUN0YUJ1dHRvblN0YXRlKCk7CiAgICB9CgogICAgYXN5bmMgZnVuY3Rpb24gaGFuZGxlQ2hlY2tvdXQoKSB7CiAgICAgIC8vIENoZWNrIGlmIHNlbGVjdGVkIHN0b3JhZ2Ugb3B0aW9uIGlzIG91dCBvZiBzdG9jayAtIHNob3cgYXZhaWxhYmlsaXR5IGRpYWxvZwogICAgICBsZXQgaXNTZWxlY3RlZFN0b3JhZ2VPdXRPZlN0b2NrID0gZmFsc2U7CiAgICAgIGlmIChzZWxlY3RlZFN0b3JhZ2UgPT09ICdiYXNlJykgewogICAgICAgIGlzU2VsZWN0ZWRTdG9yYWdlT3V0T2ZTdG9jayA9IGN1cnJlbnRBdmFpbGFibGVEZXZpY2VzID09PSAwOwogICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkU3RvcmFnZSA9PT0gJ2FkZG9uMjU2JykgewogICAgICAgIGlzU2VsZWN0ZWRTdG9yYWdlT3V0T2ZTdG9jayA9IGF2YWlsYWJsZURldmljZXNXaXRoMjU2R2JEcml2ZSA9PT0gMDsKICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZFN0b3JhZ2UgPT09ICdhZGRvbjUxMicpIHsKICAgICAgICBpc1NlbGVjdGVkU3RvcmFnZU91dE9mU3RvY2sgPSBhdmFpbGFibGVEZXZpY2VzV2l0aDUxMkdiRHJpdmUgPT09IDA7CiAgICAgIH0KCiAgICAgIGlmIChpc1NlbGVjdGVkU3RvcmFnZU91dE9mU3RvY2spIHsKICAgICAgICBvcGVuQXZhaWxhYmlsaXR5RGlhbG9nKFNUT1JBR0VfVE9fTk9USUZJQ0FUSU9OX1RZUEVbc2VsZWN0ZWRTdG9yYWdlXSk7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAvLyBTcGVjaWFsIGxvZ2ljIGZvciBkYWlseSBwbGFuIC0gcmVxdWlyZXMgbW9yZSBkZXZpY2VzIHRoYW4gdGhlIHRocmVzaG9sZAogICAgICBpZiAoc2VsZWN0ZWRDeWNsZSA9PT0gJ2RhaWx5JyAmJiBnZXRUb3RhbEF2YWlsYWJsZURldmljZXMoKSA8PSBkYWlseVBsYW5BdmFpbGFiaWxpdHlUaHJlc2hvbGQpIHsKICAgICAgICBvcGVuQXZhaWxhYmlsaXR5RGlhbG9nKEF2YWlsYWJpbGl0eU5vdGlmaWNhdGlvblR5cGUuRGFpbHkpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgY29uc3QgY3ljbGUgPSBzZWxlY3RlZEN5Y2xlOwogICAgICBjb25zdCBzdG9yYWdlID0gc2VsZWN0ZWRTdG9yYWdlOwoKICAgICAgLy8gRW5zdXJlIEFEVCBwYXlsb2FkIGV4aXN0cwogICAgICBjb25zdCBhZHRQYXlsb2FkID0gYXdhaXQgZW5zdXJlQWR0UGF5bG9hZCgpOwogICAgICBjb25zdCBjbGllbnRSZWZlcmVuY2VJZCA9IGFkdFBheWxvYWQ\/LkNsaWVudFJlZmVyZW5jZUlkID8\/IGdlbmVyYXRlR3VpZCgpOwoKICAgICAgLy8gQ2hlY2tvdXQgYWx3YXlzIGdvZXMgdG8gdGhlIFNFTEVDVEVEIGRhdGFjZW50ZXIsIHdoYXRldmVyIHRoZSBzdG9yYWdlIG9wdGlvbjogdGhlIHZpc2l0b3IKICAgICAgLy8gaXMgbmV2ZXIgc2lsZW50bHkgcHJvdmlzaW9uZWQgaW4gYSBkaWZmZXJlbnQgcmVnaW9uIGZyb20gdGhlIHRhYiB0aGV5IHBpY2tlZC4KICAgICAgY29uc3QgYmFja2VuZEtleSA9IExPQ0FUSU9OU1tzZWxlY3RlZExvY2F0aW9uXT8uYmFja2VuZEtleTsKICAgICAgaWYgKGJhY2tlbmRLZXkgPT09IHVuZGVmaW5lZCkgewogICAgICAgIHNldENoZWNrb3V0RXJyb3IoIlRoYXQgbG9jYXRpb24gaXNuJ3QgYXZhaWxhYmxlIHlldC4iKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIHNldENoZWNrb3V0RXJyb3IobnVsbCk7CiAgICAgIHNldENoZWNrb3V0QnVzeSh0cnVlKTsKICAgICAgdHJ5IHsKICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjcmVhdGVDaGVja291dFNlc3Npb24oY3ljbGUsIGJhY2tlbmRLZXksIHN0b3JhZ2UsIGNsaWVudFJlZmVyZW5jZUlkKTsKCiAgICAgICAgaWYgKHJlc3VsdC51cmwpIHsKICAgICAgICAgIHRyYWNrQWRDb252ZXJzaW9uKGNsaWVudFJlZmVyZW5jZUlkLCBjeWNsZSk7CiAgICAgICAgICAvLyBQb3B1cCBibG9ja2VycyByZWplY3Qgd2luZG93Lm9wZW4gYWZ0ZXIgYW4gYXdhaXQsIHNvIGZhbGwgYmFjayB0byB0aGlzIHRhYi4KICAgICAgICAgIGNvbnN0IG5ld1dpbmRvdyA9IHdpbmRvdy5vcGVuKHJlc3VsdC51cmwsICdfYmxhbmsnKTsKICAgICAgICAgIGlmICghbmV3V2luZG93KSB7CiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gcmVzdWx0LnVybDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFRoZSBiYWNrZW5kIG5vdyBvd25zIHRoZSBhdXRob3JpdGF0aXZlIHN0b2NrIGNoZWNrLCBzbyBpdCBjYW4gcmVmdXNlIGFmdGVyIHRoZSBjYWNoZWQKICAgICAgICAvLyBhdmFpbGFiaWxpdHkgc2FpZCB5ZXMuIE9mZmVyIHRoZSB3YWl0bGlzdCByYXRoZXIgdGhhbiBhbiBlcnJvci4KICAgICAgICBpZiAocmVzdWx0Lm91dE9mU3RvY2spIHsKICAgICAgICAgIG9wZW5BdmFpbGFiaWxpdHlEaWFsb2coU1RPUkFHRV9UT19OT1RJRklDQVRJT05fVFlQRVtzdG9yYWdlXSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzZXRDaGVja291dEVycm9yKHJlc3VsdC5lcnJvcik7CiAgICAgIH0gZmluYWxseSB7CiAgICAgICAgc2V0Q2hlY2tvdXRCdXN5KGZhbHNlKTsKICAgICAgfQogICAgfQoKICAgIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUNoZWNrb3V0U2Vzc2lvbihjeWNsZSwgZGF0YWNlbnRlciwgc3RvcmFnZSwgY2xpZW50UmVmZXJlbmNlSWQpIHsKICAgICAgY29uc3QgZ2VuZXJpY0Vycm9yID0gIkNvdWxkbid0IHN0YXJ0IGNoZWNrb3V0LiBQbGVhc2UgdHJ5IGFnYWluLiI7CiAgICAgIHRyeSB7CiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChFTkRQT0lOVF9DSEVDS09VVF9TRVNTSU9OLCB7CiAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LAogICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoewogICAgICAgICAgICBzdWJzY3JpcHRpb25UeXBlOiBDWUNMRV9UT19TVUJTQ1JJUFRJT05fVFlQRVtjeWNsZV0sCiAgICAgICAgICAgIGRhdGFjZW50ZXI6IGRhdGFjZW50ZXIsCiAgICAgICAgICAgIGV4dGVybmFsRHJpdmU6IFNUT1JBR0VfVE9fRFJJVkVfT1BUSU9OW3N0b3JhZ2VdLAogICAgICAgICAgICBjbGllbnRSZWZlcmVuY2VJZDogY2xpZW50UmVmZXJlbmNlSWQKICAgICAgICAgIH0pCiAgICAgICAgfSk7CgogICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDQyOSkgewogICAgICAgICAgcmV0dXJuIHsgdXJsOiBudWxsLCBlcnJvcjogJ1RvbyBtYW55IGNoZWNrb3V0IGF0dGVtcHRzLiBQbGVhc2Ugd2FpdCBhIG1vbWVudCBhbmQgdHJ5IGFnYWluLicsIG91dE9mU3RvY2s6IGZhbHNlIH07CiAgICAgICAgfQoKICAgICAgICAvLyBBcmRhbGlzIHJldHVybnMgYSBub24tMnh4IHN0YXR1cyBidXQgc3RpbGwgc2VuZHMgdGhlIFJlc3VsdCBib2R5OyA1MDMgbWVhbnMgc29sZCBvdXQuCiAgICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKS5jYXRjaCgoKSA9PiBudWxsKTsKICAgICAgICBpZiAocmVzcG9uc2Uub2sgJiYgcGF5bG9hZD8uaXNTdWNjZXNzICYmIHBheWxvYWQ\/LnZhbHVlPy51cmwpIHsKICAgICAgICAgIHJldHVybiB7IHVybDogcGF5bG9hZC52YWx1ZS51cmwsIGVycm9yOiBudWxsLCBvdXRPZlN0b2NrOiBmYWxzZSB9OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHVybDogbnVsbCwKICAgICAgICAgIGVycm9yOiBwYXlsb2FkPy5lcnJvcnM\/LlswXSA\/PyBnZW5lcmljRXJyb3IsCiAgICAgICAgICBvdXRPZlN0b2NrOiByZXNwb25zZS5zdGF0dXMgPT09IDUwMwogICAgICAgIH07CiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgY3JlYXRpbmcgY2hlY2tvdXQgc2Vzc2lvbjonLCBlcnJvcik7CiAgICAgICAgcmV0dXJuIHsgdXJsOiBudWxsLCBlcnJvcjogZ2VuZXJpY0Vycm9yLCBvdXRPZlN0b2NrOiBmYWxzZSB9OwogICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gc2V0Q2hlY2tvdXRFcnJvcihtZXNzYWdlKSB7CiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoZWNrb3V0RXJyb3InKTsKICAgICAgaWYgKCFlbCkgcmV0dXJuOwogICAgICBlbC50ZXh0Q29udGVudCA9IG1lc3NhZ2UgfHwgJyc7CiAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSBtZXNzYWdlID8gJ2Jsb2NrJyA6ICdub25lJzsKICAgIH0KCiAgICBmdW5jdGlvbiBzZXRDaGVja291dEJ1c3koaXNCdXN5KSB7CiAgICAgIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjdGFCdXR0b24nKTsKICAgICAgaWYgKCFidXR0b24pIHJldHVybjsKICAgICAgYnV0dG9uLmRpc2FibGVkID0gaXNCdXN5OwogICAgICBpZiAoaXNCdXN5KSB7CiAgICAgICAgYnV0dG9uLmRhdGFzZXQucHJldmlvdXNMYWJlbCA9IGJ1dHRvbi50ZXh0Q29udGVudDsKICAgICAgICBidXR0b24udGV4dENvbnRlbnQgPSAnU3RhcnRpbmcgY2hlY2tvdXTigKYnOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBpZiAoYnV0dG9uLmRhdGFzZXQucHJldmlvdXNMYWJlbCkgewogICAgICAgIGJ1dHRvbi50ZXh0Q29udGVudCA9IGJ1dHRvbi5kYXRhc2V0LnByZXZpb3VzTGFiZWw7CiAgICAgICAgZGVsZXRlIGJ1dHRvbi5kYXRhc2V0LnByZXZpb3VzTGFiZWw7CiAgICAgIH0KICAgIH0KCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gUFJJQ0UgQ0hBTkdFIE5PVElDRQogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vIElOSVRJQUxJWkFUSU9OCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICAgIGZ1bmN0aW9uIGluaXRSZW50YW1hY1ByaWNpbmcoKSB7CiAgICAgIC8vIENoZWNrIGlmIGFscmVhZHkgaW5pdGlhbGl6ZWQgdG8gcHJldmVudCBkb3VibGUgaW5pdAogICAgICBpZiAod2luZG93LnJlbnRhbWFjUHJpY2luZ0luaXRpYWxpemVkKSByZXR1cm47CiAgICAgIHdpbmRvdy5yZW50YW1hY1ByaWNpbmdJbml0aWFsaXplZCA9IHRydWU7CgogICAgICAvLyBJbml0aWFsaXplIERPTSBlbGVtZW50IHJlZmVyZW5jZXMKICAgICAgYXZhaWxhYmlsaXR5RGlhbG9nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImF2YWlsYWJpbGl0eURpYWxvZyIpOwogICAgICBhdmFpbGFiaWxpdHlPdmVybGF5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImF2YWlsYWJpbGl0eU92ZXJsYXkiKTsKICAgICAgYXZhaWxhYmlsaXR5RGlhbG9nQ2xvc2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiYXZhaWxhYmlsaXR5RGlhbG9nQ2xvc2UiKTsKICAgICAgYXZhaWxhYmlsaXR5Rm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJhdmFpbGFiaWxpdHlGb3JtIik7CiAgICAgIGF2YWlsYWJpbGl0eUZlZWRiYWNrID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImF2YWlsYWJpbGl0eUZlZWRiYWNrIik7CiAgICAgIGF2YWlsYWJpbGl0eUVtYWlsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImF2YWlsYWJpbGl0eUVtYWlsIik7CgogICAgICBxdWFudGl0eVNsaWRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJxdWFudGl0eVNsaWRlciIpOwogICAgICBkdXJhdGlvblNsaWRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkdXJhdGlvblNsaWRlciIpOwogICAgICBxdWFudGl0eVZhbHVlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInF1YW50aXR5VmFsdWUiKTsKICAgICAgZHVyYXRpb25WYWx1ZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkdXJhdGlvblZhbHVlIik7CiAgICAgIHF1YW50aXR5RGlzY291bnRCYWRnZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJxdWFudGl0eURpc2NvdW50QmFkZ2UiKTsKICAgICAgZHVyYXRpb25EaXNjb3VudEJhZGdlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImR1cmF0aW9uRGlzY291bnRCYWRnZSIpOwogICAgICBlbnRlcnByaXNlUHJpY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiZW50ZXJwcmlzZVByaWNlIik7CiAgICAgIGRpc2NvdW50QmFkZ2VFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkaXNjb3VudEJhZGdlIik7CiAgICAgIHByaWNlQnJlYWtkb3duRW50ZXJwcmlzZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJwcmljZUJyZWFrZG93bkVudGVycHJpc2UiKTsKICAgICAgbm9uQ3VtdWxhdGl2ZU5vdGljZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJub25DdW11bGF0aXZlTm90aWNlIik7CgoKICAgICAgLy8gUmVuZGVyIFVJCiAgICAgIC8vIEFsbCB0aHJlZSBza2VsZXRvbnMgYXJlIGJha2VkIGludG8gdGhlIG1hcmt1cCBhbHJlYWR5OyByZS1yZW5kZXIgdGhlbSB0b2dldGhlciBzbyB0aGVpcgogICAgICAvLyBzaGltbWVyIHN0YXlzIGluIHBoYXNlIChhbmQgdG8gY292ZXIgYSByZS1pbml0IG9uIGEgcGFnZSB0aGF0IGFscmVhZHkgcGFpbnRlZCByZWFsIGNhcmRzKS4KICAgICAgLy8gVGhlIHBpY2tlciB3YWl0cyBvbiB0aGUgZ2VvIGxvb2t1cCAoc2V0dGxlTG9jYXRpb25QaWNrZXIpLCBub3Qgb24gYXZhaWxhYmlsaXR5OyB0aGUgcmVhbAogICAgICAvLyBjeWNsZSB0YWJzIGFuZCBzdG9yYWdlIG9wdGlvbnMgYXJlIHJlbmRlcmVkIGJ5IGFwcGx5QXZhaWxhYmlsaXR5Rm9yU2VsZWN0ZWRMb2NhdGlvbigpLAogICAgICAvLyBjYWxsZWQgd2hlbiBmZXRjaEF2YWlsYWJpbGl0eVN0YXR1cygpIHJlc29sdmVzIChvciB0aGUgc2FmZXR5IHRpbWVvdXQgYmVsb3cgZmlyZXMpLgogICAgICByZW5kZXJMb2NhdGlvblRhYnNTa2VsZXRvbigpOwogICAgICByZW5kZXJDeWNsZVRhYnNTa2VsZXRvbigpOwogICAgICByZW5kZXJTdG9yYWdlT3B0aW9uc1NrZWxldG9uKCk7CiAgICAgIHVwZGF0ZVByaWNlRGlzcGxheSgpOwoKICAgICAgLy8gR2VvIHByZS1zZWxlY3Rpb24gKGNsaWVudC1zaWRlKTogZGV0ZWN0IHRoZSB2aXNpdG9yJ3MgbmVhcmVzdCBkYXRhY2VudGVyIGZyb20gdGhlaXIgSVAgYW5kCiAgICAgIC8vIHByZS1zZWxlY3QgaXQgaW4gdGhlIHBpY2tlci4gUmVzb2x2ZXMgb25jZSBhc3luY2hyb25vdXNseTsgdGhlIHZpc2l0b3IgY2FuIG92ZXJyaWRlIGl0LgogICAgICByZXNvbHZlR2VvUHJlZmVycmVkTG9jYXRpb24oKTsKCiAgICAgIC8vIFBhaW50IHRoZSBwaWNrZXIgZXZlbiBpZiBpcGFwaS5jbyBpcyBzdGlsbCBpbiBmbGlnaHQg4oCUIGEgdGhpcmQgcGFydHkgbXVzdCBub3QgaG9sZCB0aGUKICAgICAgLy8gc2tlbGV0b24gdXAgb25jZSBvdXIgb3duIGF2YWlsYWJpbGl0eSBkYXRhIGhhcyBhcnJpdmVkLgogICAgICBzZXRUaW1lb3V0KHNldHRsZUxvY2F0aW9uUGlja2VyLCBHRU9fUElDS0VSX0RFQURMSU5FX01TKTsKCiAgICAgIC8vIENUQSBidXR0b24KICAgICAgY29uc3QgY3RhQnV0dG9uID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2N0YUJ1dHRvbicpOwogICAgICBpZiAoY3RhQnV0dG9uKSBjdGFCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVDaGVja291dCk7CgogICAgICAvLyBBdmFpbGFiaWxpdHkgZGlhbG9nIGV2ZW50cwogICAgICBhdmFpbGFiaWxpdHlGb3JtPy5hZGRFdmVudExpc3RlbmVyKCJzdWJtaXQiLCBzdWJtaXRBdmFpbGFiaWxpdHlGb3JtKTsKICAgICAgYXZhaWxhYmlsaXR5RW1haWw\/LmFkZEV2ZW50TGlzdGVuZXIoImlucHV0IiwgKCkgPT4gewogICAgICAgIGF2YWlsYWJpbGl0eUZlZWRiYWNrLnRleHRDb250ZW50ID0gIldlIG9ubHkgZW1haWwgeW91IGFib3V0IGF2YWlsYWJpbGl0eS4iOwogICAgICAgIGF2YWlsYWJpbGl0eUZlZWRiYWNrLmNsYXNzTmFtZSA9ICJhdmFpbGFiaWxpdHktZmVlZGJhY2sgaW5mbyI7CiAgICAgIH0pOwogICAgICBhdmFpbGFiaWxpdHlEaWFsb2dDbG9zZT8uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCBjbG9zZUF2YWlsYWJpbGl0eURpYWxvZyk7CiAgICAgIGF2YWlsYWJpbGl0eU92ZXJsYXk\/LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgY2xvc2VBdmFpbGFiaWxpdHlEaWFsb2cpOwoKICAgICAgLy8gRmV0Y2ggYXZhaWxhYmlsaXR5IHN0YXR1cwogICAgICBmZXRjaEF2YWlsYWJpbGl0eVN0YXR1cygpOwoKICAgICAgLy8gU2FmZXR5IG5ldDogaWYgdGhlIHN0YXR1cyByZXF1ZXN0IGhhbmdzIGFuZCBuZXZlciByZXNvbHZlcy9yZWplY3RzLCBzd2FwIHRoZSBza2VsZXRvbnMgZm9yCiAgICAgIC8vIHJlYWwgY2FyZHMgKHdpdGggb3B0aW1pc3RpYyBkZWZhdWx0cykgc28gdGhlIHBhZ2UgbmV2ZXIgc3RheXMgbG9hZGluZy4gTm8tb3Agb25jZSB0aGUKICAgICAgLy8gc3RhdHVzIHBhdGggaGFzIGFscmVhZHkgc2V0dGxlZC4KICAgICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgaWYgKGF2YWlsYWJpbGl0eVN0YXR1c1NldHRsZWQpIHJldHVybjsKICAgICAgICBhdmFpbGFiaWxpdHlTdGF0dXNTZXR0bGVkID0gdHJ1ZTsKICAgICAgICBhcHBseUF2YWlsYWJpbGl0eUZvclNlbGVjdGVkTG9jYXRpb24oKTsKICAgICAgfSwgNzAwMCk7CgogICAgICAvLyBFbnN1cmUgQURUIHBheWxvYWQgZXhpc3RzIG9uIHBhZ2UgbG9hZAogICAgICBlbnN1cmVBZHRQYXlsb2FkKCk7CgogICAgICAvLyBQdXJjaGFzZSBkcm9wZG93biB0b2dnbGUKICAgICAgY29uc3QgcHVyY2hhc2VEcm9wZG93blRyaWdnZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHVyY2hhc2VEcm9wZG93blRyaWdnZXInKTsKICAgICAgY29uc3QgcHVyY2hhc2VEcm9wZG93bkNvbnRlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHVyY2hhc2VEcm9wZG93bkNvbnRlbnQnKTsKCiAgICAgIHB1cmNoYXNlRHJvcGRvd25UcmlnZ2VyPy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHsKICAgICAgICBjb25zdCBpc0V4cGFuZGVkID0gcHVyY2hhc2VEcm9wZG93blRyaWdnZXIuZ2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJykgPT09ICd0cnVlJzsKICAgICAgICBwdXJjaGFzZURyb3Bkb3duVHJpZ2dlci5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCAhaXNFeHBhbmRlZCk7CiAgICAgICAgcHVyY2hhc2VEcm9wZG93bkNvbnRlbnQuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsIGlzRXhwYW5kZWQpOwogICAgICAgIHB1cmNoYXNlRHJvcGRvd25Db250ZW50LmNsYXNzTGlzdC50b2dnbGUoJ2V4cGFuZGVkJyk7CiAgICAgIH0pOwoKICAgICAgLy8gRW50ZXJwcmlzZSBzbGlkZXIgZXZlbnRzCiAgICAgIHF1YW50aXR5U2xpZGVyPy5hZGRFdmVudExpc3RlbmVyKCJpbnB1dCIsIGNhbGN1bGF0ZUVudGVycHJpc2VQcmljZSk7CiAgICAgIGR1cmF0aW9uU2xpZGVyPy5hZGRFdmVudExpc3RlbmVyKCJpbnB1dCIsIGNhbGN1bGF0ZUVudGVycHJpc2VQcmljZSk7CgogICAgICAvLyBJbml0aWFsIGVudGVycHJpc2UgY2FsY3VsYXRpb24KICAgICAgaWYgKHF1YW50aXR5U2xpZGVyICYmIGR1cmF0aW9uU2xpZGVyKSB7CiAgICAgICAgY2FsY3VsYXRlRW50ZXJwcmlzZVByaWNlKCk7CiAgICAgIH0KCiAgICAgIC8vIExvYWQgR29vZ2xlIFJldmlld3MKICAgICAgbG9hZEdvb2dsZVJldmlld3MoKTsKICAgIH0KCiAgICAvLyBSdW4gaW5pdDogaWYgRE9NIGFscmVhZHkgbG9hZGVkLCBydW4gaW1tZWRpYXRlbHk7IG90aGVyd2lzZSB3YWl0CiAgICBpZiAoZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnKSB7CiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBpbml0UmVudGFtYWNQcmljaW5nKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIERPTSBhbHJlYWR5IGxvYWRlZCAoY29tbW9uIGluIFdvcmRQcmVzcyBlbWJlZHMpCiAgICAgIGluaXRSZW50YW1hY1ByaWNpbmcoKTsKICAgIH0KCiAgICAvLyBFeHBvc2UgbmF2aWdhdGVXaXRoTGFuZ3VhZ2UgdG8gZ2xvYmFsIHNjb3BlIGZvciBvbmNsaWNrIGhhbmRsZXJzCiAgICB3aW5kb3cubmF2aWdhdGVXaXRoTGFuZ3VhZ2UgPSBuYXZpZ2F0ZVdpdGhMYW5ndWFnZTsKICAgIH0pKCk7CiAg\");var a=new Uint8Array(b.length);for(var i=0;i<b.length;i++){a[i]=b.charCodeAt(i);}var u=URL.createObjectURL(new Blob([a],{type:\"text\/javascript;charset=utf-8\"}));var s=document.createElement(\"script\");s.src=u;s.onload=function(){URL.revokeObjectURL(u);};document.head.appendChild(s);}catch(e){console.error(\"rentamac pricing bootstrap failed\",e);}})();<\/script>\n","protected":false},"excerpt":{"rendered":"<p>All instances are currently allocated &times; We&#8217;re at full capacity right now, but we can let you know the moment a Mac becomes available again. Leave your email below and you&#8217;ll be first in line when we spin up new instances. Email address Notify me We only use this email to update you about availability. [&hellip;]<\/p>\n","protected":false},"author":9,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-26","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/pages\/26","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/comments?post=26"}],"version-history":[{"count":649,"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/pages\/26\/revisions"}],"predecessor-version":[{"id":5444,"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/pages\/26\/revisions\/5444"}],"wp:attachment":[{"href":"https:\/\/rentamac.io\/ar\/wp-json\/wp\/v2\/media?parent=26"}],"curies":[{"name":"\u062f\u0628\u0644\u064a\u0648 \u0628\u064a","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}