<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yitzi Ginzberg</title>
    <description>The latest articles on DEV Community by Yitzi Ginzberg (@yitzi).</description>
    <link>https://dev.to/yitzi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F139281%2F98469f4d-bc27-448c-9b87-ec3222c2bbd9.jpeg</url>
      <title>DEV Community: Yitzi Ginzberg</title>
      <link>https://dev.to/yitzi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yitzi"/>
    <language>en</language>
    <item>
      <title>Mastering 3D Experiences with JavaScript and Wix: A Step-by-Step Guide</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Sun, 10 Mar 2024 13:56:13 +0000</pubDate>
      <link>https://dev.to/yitzi/mastering-3d-experiences-with-javascript-and-wix-a-step-by-step-guide-3ojm</link>
      <guid>https://dev.to/yitzi/mastering-3d-experiences-with-javascript-and-wix-a-step-by-step-guide-3ojm</guid>
      <description>&lt;h3&gt;
  
  
  Setting Up the Environment
&lt;/h3&gt;

&lt;p&gt;In my last post, we explored making unique and stunning websites using 3D Gaussian splatting. Today, we dive deeper, showing you how to augment your Gaussian splat with JavaScript for mind-blowing 3D web experiences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with Package Downloads
&lt;/h3&gt;

&lt;p&gt;Before we jump into coding, let's set the stage. Our focus in this session will be on using the Luma web library. For this demonstration, I'm using Wix, but feel free to adapt the process to your preferred setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Workspace in Wix
&lt;/h3&gt;

&lt;p&gt;We start by navigating to Wix.com, creating a new site, and opting for a blank canvas. Turning on the developer mode, we then proceed to embed a custom element. After adjusting the custom element to fill the screen area, we specify the source for our code, either through hosting or creating a new Velo file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Importing Necessary Packages
&lt;/h3&gt;

&lt;p&gt;To harness the full potential of our 3D setup, we install the Luma web package and Three.js from NPM through the Wix interface. These packages form the backbone of our 3D web experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diving into Custom Element Coding
&lt;/h3&gt;

&lt;p&gt;With our packages installed, we dive into coding the custom element. This involves setting up the renderer, camera, and scene with Three.js, crucial components for rendering 3D graphics on the web.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/JpDTuFTEsx0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Exploring Wix IDE and VS Code Integration
&lt;/h3&gt;

&lt;p&gt;One neat feature is the ability to integrate the Wix IDE with VS Code. This synchronization allows for a more streamlined coding experience, especially helpful when dealing with complex 3D rendering code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting to GitHub and Finalizing the Project
&lt;/h3&gt;

&lt;p&gt;The project is then connected to GitHub for version control and collaborative development. This step involves installing the Velo application and setting up a new repository for our project.&lt;/p&gt;

&lt;p&gt;During the setup, I switched to a local IDE for better integration with tools like GitHub Copilot, which aids in writing more efficient and error-free code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing Advanced Visuals with LumaSplatsThree
&lt;/h3&gt;

&lt;p&gt;The heart of our session lies in integrating LumaSplats3 for dynamic, interactive 3D visuals. The renderer is appended to our custom element, and with a few lines of code, our Gaussian splat comes to life, responsive to user interactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Up: Previewing and Publishing
&lt;/h3&gt;

&lt;p&gt;Finally, we preview our project locally and then publish it to Wix. The result is a live, interactive 3D scene, accessible to anyone visiting the site.&lt;/p&gt;

&lt;p&gt;And that's a wrap for this session! We've successfully integrated a Gaussian splat into our website using JavaScript and the Luma web library. In the next videos, I'll take you through adding those extra touches that elevate your 3D web experience. Stay tuned!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Revolutionizing Web Experiences with AI-Generated 3D Scenes</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Tue, 27 Feb 2024 21:04:46 +0000</pubDate>
      <link>https://dev.to/yitzi/revolutionizing-web-experiences-with-ai-generated-3d-scenes-3oj</link>
      <guid>https://dev.to/yitzi/revolutionizing-web-experiences-with-ai-generated-3d-scenes-3oj</guid>
      <description>&lt;p&gt;The field of web development has undergone a significant transformation due to recent AI advancements. Now, creating impressive 3D web experiences from just a few photos is possible, thanks to AI technology.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to 3D Web Experiences with AI
&lt;/h3&gt;

&lt;p&gt;Creating 3D models or environments traditionally required a team, resources, and time. NERFs and Radiance Field Technologies changed this, enabling the creation of 3D models more efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Game Changer: 3D Gaussian Splatting
&lt;/h3&gt;

&lt;p&gt;A groundbreaking paper in August introduced 3D Gaussian splatting. This innovation makes it possible to create stunning 3D web experiences that render in real time.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1762574552595386478-980" src="https://platform.twitter.com/embed/Tweet.html?id=1762574552595386478"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1762574552595386478-980');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1762574552595386478&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Luma AI for Gaussian Splat Generation
&lt;/h3&gt;

&lt;p&gt;Luma AI simplifies generating Gaussian splats from videos. By uploading a video, Luma AI extracts frames to create a Gaussian splat, facilitating the creation of dynamic 3D environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exploring Generated 3D Scenes
&lt;/h3&gt;

&lt;p&gt;Gaussian splats enable immersive exploration of 3D scenes on the web. Users can interact with detailed scenes from new angles, thanks to AI's rendering capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Magic of AI in 3D Scene Creation
&lt;/h3&gt;

&lt;p&gt;Gaussian splatting excels at creating detailed 3D scenes, handling tasks like rendering reflections and shadows. This technology democratizes 3D scene creation, making it accessible to anyone with a phone camera.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Immersive Interactive Experiences
&lt;/h3&gt;

&lt;p&gt;AI-generated 3D models offer endless possibilities for interactive web experiences. Developers can enhance user engagement by allowing interactions with scenes through various input devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of Interactive 3D Scene on a Website
&lt;/h3&gt;

&lt;p&gt;Interactive 3D scenes can blend reality and fiction on websites. Platforms like Wix empower creators to experiment and innovate rapidly without DevOps, fostering limitless creative expression.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion and Teaser for Next Video
&lt;/h3&gt;

&lt;p&gt;AI-generated 3D scenes are shaping the future of web experiences. Stay tuned for our next video, exploring the creation of interactive 3D scenes without costly software or equipment.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>3d</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building a WhatsApp Chatbot with Wix Headless API: A Developer's Journey</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Wed, 24 May 2023 12:21:58 +0000</pubDate>
      <link>https://dev.to/yitzi/building-a-whatsapp-chatbot-with-wix-headless-api-a-developers-journey-5b9p</link>
      <guid>https://dev.to/yitzi/building-a-whatsapp-chatbot-with-wix-headless-api-a-developers-journey-5b9p</guid>
      <description>&lt;p&gt;Hello Dev Community! I'm Yitzi, a Creative Technologist at Wix and a chatbot enthusiast. Today, I want to share a project I've been working on - a WhatsApp chatbot that integrates with a Wix store. This chatbot allows customers to browse products, add items to their cart, and proceed to checkout - all within WhatsApp.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concept
&lt;/h2&gt;

&lt;p&gt;The chatbot uses the Wix Headless API to communicate with the Wix store. It fetches product information, manages the shopping cart, and handles the checkout process. Any changes made to the store, such as adding new products or adjusting prices, are automatically reflected in the chatbot.&lt;/p&gt;

&lt;p&gt;You can find the code for the chatbot on &lt;a href="https://github.com/YitziG/wa-store"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YKZUahiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5ehguix5fhtnptarlom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YKZUahiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5ehguix5fhtnptarlom.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Components
&lt;/h2&gt;

&lt;p&gt;Here are the key components of the chatbot:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;wix_client.mjs&lt;/strong&gt;: Sets up the Wix API client and handles OAuth authentication, enabling the chatbot to communicate with the Wix store through the Headless API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;message_handler.mjs&lt;/strong&gt;: Handles incoming WhatsApp messages and user interactions, managing the chat flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;products_api.mjs&lt;/strong&gt;: Retrieves the available products from the Wix store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;token_management.mjs&lt;/strong&gt;: Manages user tokens and authentication for the Wix API, allowing the chatbot to interact with the Wix store on behalf of individual users.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;The chatbot guides customers through the entire shopping process, providing a product catalog view, individual product information (including images), and options to add items to the cart or proceed to the checkout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ovZV8Uqo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axfq86tx2e2bs12q825p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ovZV8Uqo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axfq86tx2e2bs12q825p.png" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a brief overview of the flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The chatbot displays the product catalog, allowing users to browse available products. Users can select a product by sending the corresponding number.&lt;/li&gt;
&lt;li&gt;The chatbot then displays detailed information and an image of the selected product. Users can add the selected product to their cart.&lt;/li&gt;
&lt;li&gt;The chatbot confirms the product has been added to the cart and displays the current cart items. Customers can either proceed to checkout or return to the product list to continue shopping.&lt;/li&gt;
&lt;li&gt;When users are ready to check out, the chatbot provides a link to complete the payment process on the store's website.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--euoGN4XY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5u7gxmig01c4fgcimjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--euoGN4XY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5u7gxmig01c4fgcimjb.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Details
&lt;/h2&gt;

&lt;p&gt;The chatbot uses the Wix Headless Node SDK to fetch the list of available products in the store and maintains the state of each user's interaction with the store. It uses the user's current state to determine how to respond to their input, such as displaying a list of products, showing details about a specific product, or adding an item to their cart.&lt;/p&gt;

&lt;p&gt;To add items to the user's cart, the chatbot calls the &lt;code&gt;wixClient.currentCart.addToCurrentCart()&lt;/code&gt; method. When the user is ready to check out, the chatbot creates a checkout session using the &lt;code&gt;wixClient.currentCart.createCheckoutFromCurrentCart()&lt;/code&gt; method and provides the user with a link to complete their purchase on the Wix store's website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g4Qmg-Y---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ox24onqf8cfehtdp5aug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g4Qmg-Y---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ox24onqf8cfehtdp5aug.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This project showcases how the Wix Headless API can be used to create engaging and unique shopping experiences across multiple platforms. As a developer and a chatbot enthusiast, I found this project to be a fascinating exploration of the potential of chatbots and the Wix Headless API.&lt;/p&gt;

&lt;p&gt;In fact, I'm so obsessed with building chatbots that I've even created an AI rabbi that has been dispensing advice for over a year! This WhatsApp chatbot is just another step in my journey of exploring the possibilities of chatbot technology.&lt;/p&gt;

&lt;p&gt;I'd love to hear your thoughts on this project. Have you worked with the Wix Headless API before? Do you have any experiences or insights to share? Let's start a discussion in the comments below!&lt;/p&gt;

&lt;p&gt;If you want to follow my journey and see more of my projects, feel free to check out my &lt;a href="http://hopp.to/yitzi"&gt;link-in-bio&lt;/a&gt; where you can connect with me on various social platforms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/YitziG/wa-store" class="ltag_cta ltag_cta--branded"&gt;Check out the GitHub repository for the WhatsApp chatbot&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;Big thanks to Pedro López, whose &lt;a href="https://github.com/pedroslopez/whatsapp-web.js"&gt;&lt;code&gt;whatsapp-web.js&lt;/code&gt;&lt;/a&gt; was a lifesaver for this project. Pedro's work stands as a testament to the power of open source - it's been a great learning resource for me, and the backbone of my WhatsApp chatbot. Do check it out, it's worth it. Cheers, Pedro!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>api</category>
      <category>chatbots</category>
      <category>whatsap</category>
    </item>
    <item>
      <title>Easy Project That Will Make You Famous</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Tue, 01 Feb 2022 09:54:19 +0000</pubDate>
      <link>https://dev.to/yitzi/easy-project-that-will-make-you-famous-4kn4</link>
      <guid>https://dev.to/yitzi/easy-project-that-will-make-you-famous-4kn4</guid>
      <description>&lt;p&gt;Are you a developer or CS student looking for an easy project that will make you famous?&lt;/p&gt;

&lt;p&gt;Create a Zoom app that announces "${name}, you're muted", every time someone starts screen sharing.&lt;/p&gt;

&lt;p&gt;Use Zoom's "user.presence_status_updated" webhook to trigger the alert whenever a user's "presence_status" is updated to "Presenting."&lt;/p&gt;

&lt;p&gt;Here's the documentation you need: &lt;a href="https://marketplace.zoom.us/docs/api-reference/zoom-api/events/#/paths/user.presence_status_updated/post"&gt;https://marketplace.zoom.us/docs/api-reference/zoom-api/events/#/paths/user.presence_status_updated/post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You're welcome!&lt;/p&gt;

</description>
      <category>sideprojects</category>
      <category>100daysofcode</category>
      <category>career</category>
    </item>
    <item>
      <title>You Missed the Most Important Detail in This Video!</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Tue, 21 Dec 2021 11:05:59 +0000</pubDate>
      <link>https://dev.to/aws-builders/you-missed-the-most-important-detail-in-this-video-466l</link>
      <guid>https://dev.to/aws-builders/you-missed-the-most-important-detail-in-this-video-466l</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/7_vWwjSHs64"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;There is a hidden gem in this video. Pause at 0:10, and you'll see the command: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx sled-test-runner&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What the heck is this?&lt;/p&gt;

&lt;p&gt;To allow our developers to do their best work, we removed the hoops they would usually need to jump through to get their code into production.&lt;/p&gt;

&lt;p&gt;Obviously (well, at least in retrospect), we needed to cut out QA. Dev servers are also out.&lt;/p&gt;

&lt;p&gt;Wix decided to trust its developers to push code to production directly from their local dev machines.&lt;/p&gt;

&lt;p&gt;Are we crazy? Yes. But not in that way.&lt;br&gt;
How can we cut out these parts without compromising on the robustness of our production apps? How can we allow vast amounts of developers on different continents to push code to interdependent apps without breaking or stuff or negatively impacting performance? &lt;/p&gt;

&lt;p&gt;Hundreds of millions of people rely on our online services to run their businesses!&lt;/p&gt;

&lt;p&gt;Obviously, we will need some serious testing, but with each developer doing their own deployments, this means thousands of deployments per day, with each one triggering thousands of tests!&lt;/p&gt;

&lt;p&gt;This means MILLIONS of unique test executions PER WEEK!&lt;br&gt;
How can we possibly handle this? How long will developers have to wait for all these test results? We can't make them wait an hour every time they merge into the master branch, just to find out if their code passed inspection!&lt;/p&gt;

&lt;p&gt;Luckily we found a way to do all of this in just about the same amount of time it takes to run a single test on your local machine!&lt;/p&gt;

&lt;p&gt;Meet Sled.&lt;br&gt;
SLED is our end-to-end testing platform.&lt;/p&gt;

&lt;p&gt;Leveraging cloud computing to run all project test files in parallel, Sled allows us to run end-to-end browser tests against production without sacrificing speed.&lt;/p&gt;

&lt;p&gt;We even run each test multiple times in parallel with itself so that we don't need to spend time rerunning flaky tests!&lt;/p&gt;

&lt;p&gt;SLED uses open source technologies such as Chromium, Jest, and Puppeteer to orchestrate the parallel run of hundreds of concurrent tests using AWS Lambda as the underlying compute. &lt;/p&gt;

&lt;p&gt;In addition, SLED is integrated into developers’ machines to deliver a completely seamless developer experience that responds as if the test was executed locally.&lt;/p&gt;

&lt;p&gt;Developers at Wix can invoke upwards of a thousand different browsers, running a thousand different tests, and get the results from their laptops in two or three minutes!&lt;br&gt;
Interested in learning more? Check out this video that outlines the architecture we use!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/hbz63Ve-eIY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Wanna try it out? It sounds complicated, but it's actually not that hard to implement!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/AsUAA8jsDAo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In this talk, Tom explains how this solution works and how you can adapt its core components to make it work for your project. &lt;/p&gt;

&lt;p&gt;Tom will walk you step-by-step through an open-source project on Github that you can clone, experiment with, and even adapt to your own needs.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Creating Unique Video Dashboards for Individual Users Is Easier than You Would Imagine… If You Are Using api.video😉</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Thu, 30 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/api_video/creating-unique-video-dashboards-for-individual-users-is-easier-than-you-would-imagine-if-you-are-using-api-video-54in</link>
      <guid>https://dev.to/api_video/creating-unique-video-dashboards-for-individual-users-is-easier-than-you-would-imagine-if-you-are-using-api-video-54in</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--teuKS38S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/design-desk-display-eyewear-313690_4c94524b088e9f195cac811221aa4664_1000.jpg" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--teuKS38S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/design-desk-display-eyewear-313690_4c94524b088e9f195cac811221aa4664_1000.jpg" width="880" height="660"&gt;&lt;/a&gt;Frustrated Teacher&lt;/p&gt;

&lt;p&gt;If you have kids or know anybody that has kids, then you’ve probably been exposed to the frustration surrounding the rapid and non-optional transition from a classroom learning environment to a remote one.&lt;/p&gt;

&lt;p&gt;One of the primary sources of frustration for teachers and parents stems from the need for teachers and students to adopt new technology with which they are unfamiliar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Imagine that you are a developer in the booming field of e-learning. Since you are smart, one of your primary goals is to make the interface as self-explanatory and straightforward as possible for teachers and students.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To accomplish that, you may decide that each student or teacher who logs in should, by default, see only videos relevant to them on their dashboard.&lt;/p&gt;

&lt;p&gt;Implementing such customization may seem like a herculean task. After all, you’ve got hundreds of teachers and students and thousands of videos.   &lt;/p&gt;

&lt;p&gt;Don’t fret. It’s quite easy with api.video’s API.&lt;/p&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  A Bird’s Eye View
&lt;/h2&gt;

&lt;p&gt;Before looking at any code, let’s restate the problem. I’ll begin with the teacher's use case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; We have many teachers uploading videos, and we want each teacher to see only their videos on their dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; We make use of api.video’s &lt;strong&gt;tagging&lt;/strong&gt; feature on our backend.&lt;/p&gt;

&lt;p&gt;There are two reasons for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We want to make this as simple as possible. This implementation is entirely invisible to the teachers and requires no action from them, not even a checkbox. &lt;/li&gt;
&lt;li&gt;Having implemented a login on our backend means that we are holding a unique identifier (i.e., username, id) for our logged-in user. That makes tagging and accurate retrieval a breeze.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Upload
&lt;/h2&gt;

&lt;p&gt;For simplicities sake, let’s assume that students and teachers share a table in our database that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email_address&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;password_hash&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a teacher logs in, we query this table to authenticate them. It’s trivial to grab the unique username at the same time.&lt;/p&gt;

&lt;p&gt;Every time the logged-in teacher uploads a video, we include their “username/tag” in the ‘Create video’ request we make to the api.video API.&lt;/p&gt;

&lt;p&gt;When &lt;a href="https://docs.api.video/5.1/videos/create-video"&gt;creating the video&lt;/a&gt;, you can include tags in the request body like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Maths video"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"An amazing video explaining the string theory"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"einstein"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can take this a step further, allowing the teacher to select which course they are uploading the video to and adding a tag for that as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieving the Users Video’s
&lt;/h2&gt;

&lt;p&gt;Every video is now associated with the unique identifier of the uploader. When a teacher logs into his video dashboard, all we need to do on the backend is to add their unique identifier to the query string when requesting the video list from api.video’s API.&lt;/p&gt;

&lt;p&gt;For example, if the teacher's unique tag is “einstein,” our request would look like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; GET &lt;span class="se"&gt;\ &lt;/span&gt;
      &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s1"&gt;'https://ws.api.video/videos?tags=einstein'&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;
      &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'authorization: dgsgsdgsdgsdg'&lt;/span&gt; &lt;span class="se"&gt;\ &lt;/span&gt;
      &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our backend would get a response from api.video’s API that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"assets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.api.video/stream/89-9f9-8ae/hls/manifest.m3u8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"iframe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;iframe src='//embed.api.video/58-3403-46?token=89-9f9-8ae' width='100%' height='100%' frameborder='0' scrolling='no' allowfullscreen=''&amp;gt;&amp;lt;/iframe&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"mp4"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.api.video/vod/dRAEjQ/token/443-d9f0-45/mp4/720/source.mp4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"player"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://embed.api.video/58-3403-46?token=89-9f9-8ae"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"thumbnail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.api.video/stream/89-9f9-8ae/thumbnail.jpg"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"An amazing video explaining the string theory"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"mp4Support"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"panoramic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"playerId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pl45KFKdlddgk654dspkze"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"publishedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2019-12-16T08:25:51+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/videos/58-3403-46/source"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"einstein"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"maths"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"string theory"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"video"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Maths video"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"updateddAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2019-12-16T08:48:49+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"videoId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"58-3403-46"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pagination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currentPage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currentPageItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"itemsTotal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ws.api.video/videos?currentPage=1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"first"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ws.api.video/videos?currentPage=1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"last"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ws.api.video/videos?currentPage=1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pageSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pagesTotal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then handle that response however we’d like, passing on to the client app whichever properties we choose, confident that this user uploaded these videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about the Students?
&lt;/h2&gt;

&lt;p&gt;Applying the above technique to provide each student with a video dashboard tailored to them is simple.&lt;/p&gt;

&lt;p&gt;Let’s say we have a table for courses that lists all the essential info for each course.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our lookup table could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;student_course_lookup&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt;   &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;course_id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;course_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a student logs in, it's a simple query to get the tags of all their courses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
         &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;student_course_lookup&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this information, we can display a friendly UI allowing the student to choose which course they would like to see from a personalized course list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xj4yQyld--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_8f8e9b0ec7b4ce5a7993857e8a282e35_1000.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xj4yQyld--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_8f8e9b0ec7b4ce5a7993857e8a282e35_1000.PNG" width="880" height="515"&gt;&lt;/a&gt;Screenshot from Udacity for illustration only.&lt;/p&gt;

&lt;p&gt;Based on their selection, we’ll request their videos from our backend with the appropriate tag attached.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; GET &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; &lt;span class="s1"&gt;'https://ws.api.video/videos?tags=html-intro'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'authorization: dgsgsdgsdgsdg'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then pass the required fields from the response back to the client UI&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dRibJ3Sk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture2_743fde0dfc0474d49cad8541305cca8a_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--dRibJ3Sk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture2_743fde0dfc0474d49cad8541305cca8a_800.PNG" width="800" height="394"&gt;&lt;/a&gt;Screenshot from Udacity for illustration only.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;That’s all folks!&lt;/p&gt;

&lt;p&gt;I hope you’ve got the picture. Remember, our community is here for you at &lt;a href="http://community.api.video"&gt;community.api.video&lt;/a&gt;, and you can always reach out to me directly at &lt;a href="mailto:yitzi@api.video"&gt;yitzi@api.video&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Video Tags can Make Your App Awesome, Here’s How to Use Them.</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Wed, 22 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/api_video/video-tags-can-make-your-app-awesome-here-s-how-to-use-them-2o23</link>
      <guid>https://dev.to/api_video/video-tags-can-make-your-app-awesome-here-s-how-to-use-them-2o23</guid>
      <description>&lt;p&gt;Having a reliable way to filter videos based on specific criteria is a must for most video apps.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An e-learning site may want to display different videos to each user, depending on their class list.&lt;/li&gt;
&lt;li&gt;An animal adoption center may choose to display only videos of cats to cat-lovers.&lt;/li&gt;
&lt;li&gt;A site that allows users to upload videos may not want those videos displayed until they get approved by an admin. &lt;/li&gt;
&lt;li&gt;A fan site may have different levels of membership, where each level gets granted access to additional videos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generally, implementing something like this involves much work, takes lots of development time, clutters up your codebase, and can easily lead to bugs and data loss.&lt;/p&gt;

&lt;p&gt;It is true that api.video is an API for video. However, we are also an API for &lt;strong&gt;developers&lt;/strong&gt;! That is why we decided to include a video tagging and filtering system right into our API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tags to the Rescue!
&lt;/h2&gt;

&lt;p&gt;api.video’s tagging feature allows you to add tags to each video. Tags can be applied to a video when it is initially created and updated at any point after that.  &lt;/p&gt;

&lt;p&gt;You can manage your tags using api.video’s web interface as well as directly through the API.&lt;/p&gt;

&lt;p&gt;The web interface is useful for learning about tags and for managing them if you have a small number of videos.  &lt;/p&gt;

&lt;p&gt;If you are dealing with a large number of videos or need tags to be assigned automatically, then you should use the API. Don’t worry. It’s a piece of cake!&lt;/p&gt;

&lt;p&gt;The easiest way to understand tags is to begin using them, so let’s get started.  &lt;/p&gt;

&lt;p&gt;Let’s begin with the web UI and then move on to the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tagging Videos (Web UI)
&lt;/h2&gt;

&lt;p&gt;Visit your video dashboard at &lt;a href="https://go.api.video"&gt;go.api.video&lt;/a&gt;. If you do not yet have an account, create one when prompted.&lt;/p&gt;

&lt;p&gt;Once you are on your dashboard, you can see your video thumbnails with your most recent uploads first. If you have not yet uploaded any videos, what are you waiting for? Click the blue-button and upload a few. If you don’t have any videos to upload, grab a few from &lt;a href="https://www.pexels.com/videos/"&gt;pexels.com/videos&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;My dash looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QGf_tEiw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/dash_828d1066735dd474873e798faf29b15b_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--QGf_tEiw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/dash_828d1066735dd474873e798faf29b15b_800.PNG" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s say I’m the founder and lead developer of petvids.com, the hottest new start-up out of Silicon Valley. I want to provide pet-lovers with the option of choosing whether they would rather see dog videos or cat videos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vJZcfex3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/petvids_cadfcfc1c2d8d9e3f0cf8db6e4126f70_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJZcfex3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/petvids_cadfcfc1c2d8d9e3f0cf8db6e4126f70_800.PNG" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the web UI, I can easily click on each video, select “edit video” in the “actions” section, and add the appropriate tag.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RgdFxhEt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/tags_75e4b145169cc27c454af6546aa34dfa_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--RgdFxhEt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/tags_75e4b145169cc27c454af6546aa34dfa_800.PNG" width="762" height="766"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can demonstrate that the tags are working using the web UI.&lt;/p&gt;

&lt;p&gt;This is what I get if I filter for videos with the tag “cat”:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EvsJbUSQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/cat_f46d71781018d9277f0bb496f9852449_1000.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EvsJbUSQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/cat_f46d71781018d9277f0bb496f9852449_1000.PNG" width="880" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Filtering for “dog” gets me:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P8Z-RB5t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture2_4628ffdaa5791205248152db8186c72b_1000.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--P8Z-RB5t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture2_4628ffdaa5791205248152db8186c72b_1000.PNG" width="880" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think you get the basic idea. Let’s look at how to implement this in the backend of your app using our API.&lt;/p&gt;

&lt;h2&gt;
  
  
  API and Additional Queries
&lt;/h2&gt;

&lt;p&gt;Using our API, you can request a list of all videos with the /videos endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://ws.api.video/videos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and if you want to see the videos that you uploaded in “sandbox” mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://sandbox.api.video/videos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you have authenticated and are making the request with your “auth” token in the header. More on that &lt;a href="https://docs.api.video/5.1/videos-and-streaming/Authentication-tutorial"&gt;here&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;You can see what this request looks like in different frameworks and libraries &lt;a href="https://docs.api.video/5.1/videos/list-videos"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mTRIB44F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_bc36aeb40326e4bdb5f942f394dcdf6e_1000.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--mTRIB44F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_bc36aeb40326e4bdb5f942f394dcdf6e_1000.PNG" width="880" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can try out this request directly from our documentation! Just be sure to authenticate first and then to copy your token into the authorization header.&lt;/p&gt;

&lt;h3&gt;
  
  
  Filtering by Tags
&lt;/h3&gt;

&lt;p&gt;To filter by tags you need only add a ‘tags’ query param with a comma-separated list of values, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://ws.api.video/videos?tags=white
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In response, I get a list of the following videos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yw-9Lgei--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture5_df1cae729dabf5e0adb544dd5e169bd4_1000.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yw-9Lgei--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture5_df1cae729dabf5e0adb544dd5e169bd4_1000.PNG" width="880" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take note that videos can contain additional tags that are not in the query string. In this case, each video has an additional tag of either cat or dog.&lt;/p&gt;

&lt;p&gt;Let’s see another example.&lt;/p&gt;

&lt;p&gt;What if I want to allow the user to choose to see only videos of brown dogs?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://ws.api.video/videos?tags=dog,brown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gUR0_330--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture3_bc63f7cb730b9250f8397c81ee557932_1000.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--gUR0_330--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture3_bc63f7cb730b9250f8397c81ee557932_1000.PNG" width="880" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That does the trick!  &lt;/p&gt;

&lt;p&gt;A word of caution. A video must have ALL the tags that you are filtering for to be returned to you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pgpr5sX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture4_5204ecb935147d546ecfdff4009d2239_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--pgpr5sX3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture4_5204ecb935147d546ecfdff4009d2239_800.PNG" width="373" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Searching for “dog” and “cat” does not return videos with “either” tag. It returns videos with “both” tags, in this case, none. To get all videos tagged “cat” or “dog,” you need to make two separate queries.&lt;/p&gt;

&lt;p&gt;I hope that clarifies how you can set and update tags using our web UI and how to filter videos by tag(s) with our web UI and API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting, Updating, and Deleting Tags via the API
&lt;/h3&gt;

&lt;p&gt;Setting, updating, and deleting tags via the API is pretty straightforward.&lt;/p&gt;

&lt;p&gt;When &lt;a href="https://docs.api.video/5.1/videos/create-video"&gt;creating the video&lt;/a&gt;, you can include tags in the request body like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "title": "Maths video", "description": "An amazing video explaining the string theory", "tags": ["maths", "string theory", "video"]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To update or delete tags later, use the &lt;a href="https://docs.api.video/5.1/videos/update-a-video"&gt;video update endpoint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Something to be aware of:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you include a tags list when updating your video, the list of the existing tags gets overwritten by the new list. If you want only to add new tags and not lose or change existing ones, you need to include the old ones in the update request. To get the current tags, use the &lt;a href="https://docs.api.video/5.1/videos/get-video"&gt;“Get video” endpoint&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;I hope you feel ready to get started! If you have any questions, don’t hesitate to ask our friendly community of users and experts at &lt;a href="https://community.api.video"&gt;community.api.video&lt;/a&gt;. Thanks for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I built a local TV station to keep myself and my kids occupied. You can too!</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Tue, 07 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/api_video/i-built-a-local-tv-station-to-keep-myself-and-my-kids-occupied-you-can-too-43bi</link>
      <guid>https://dev.to/api_video/i-built-a-local-tv-station-to-keep-myself-and-my-kids-occupied-you-can-too-43bi</guid>
      <description>&lt;p&gt;It must have been over a hundred degrees inside the panda suit, but I wasn't complaining. I felt a sense of fulfillment, unlike anything I had ever felt before.&lt;/p&gt;

&lt;p&gt;It would be totally fair for you to ask what I was doing in the said panda suit and why I'm claiming that I was happy with that situation. I can't promise to settle all the doubts in your mind, but I'll give it my best shot.&lt;/p&gt;




&lt;p&gt;Take a look at this photo:&lt;br&gt;
            &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4JkQTU5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/IMG_20200319_070058_fa072b72d4c4717edbc64d195e1abe8d_800.jpg" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--4JkQTU5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/IMG_20200319_070058_fa072b72d4c4717edbc64d195e1abe8d_800.jpg" width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
        &lt;/p&gt;

&lt;p&gt;That's my son, the apple of my eye, on day number eleven of this wretched lockdown.&lt;/p&gt;

&lt;p&gt;And he's not the only one who felt this way. The thrill of an unexpected and "until further notice" vacation was wearing off on my older girls as well and they were beginning to get BORED:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
                                    &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XseLy9Io--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d37oebn0w9ir6a.cloudfront.net/account_21166/AnimatedGIF-downsized_large_f43ec9136fe22edb4910c2164c1e250a.gif" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--XseLy9Io--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d37oebn0w9ir6a.cloudfront.net/account_21166/AnimatedGIF-downsized_large_f43ec9136fe22edb4910c2164c1e250a.gif" width="360" height="480"&gt;&lt;/a&gt;&lt;br&gt;
        &lt;/p&gt;

&lt;p&gt;I was also getting bored with teaching fourth-grade math and kindergarten level English.&lt;/p&gt;

&lt;p&gt;To complicate matters, I had just started a new job at &lt;a href="https://api.video/"&gt;api.video&lt;/a&gt; and needed to get familiar with their &lt;a href="https://docs.api.video/5.1/introduction/api-endpoints"&gt;video API&lt;/a&gt;. I love working from home as much as anybody. Still, even the most optimistic, "look on the bright side," type of person, would not call what those of us with kids are trying to accomplish, "working from home." More like "suffer from home."&lt;br&gt;
&lt;br&gt;
                                    &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BVcY_jR---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d37oebn0w9ir6a.cloudfront.net/account_21166/IMG_20200117_132251-ANIMATION_30dcead609975d00f5a594b9c2a17d75.gif" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--BVcY_jR---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d37oebn0w9ir6a.cloudfront.net/account_21166/IMG_20200117_132251-ANIMATION_30dcead609975d00f5a594b9c2a17d75.gif" width="606" height="808"&gt;&lt;/a&gt;&lt;br&gt;He's cute, but I can't work like this.
        &lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;I realized that it was up to me to keep my family from imploding. I needed to think of an idea, a mission, if you will. Something to give meaning to this endless stream of days.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What I was looking for was a family goal. A challenge that would inspire my kids and fire up their imaginations. It also needed to be something that would be fun and challenging for me.&lt;/p&gt;

&lt;p&gt;Yet another requirement was that it needed to enable me to get &lt;strong&gt;actual&lt;/strong&gt; work done.&lt;/p&gt;

&lt;p&gt;This all seemed impossible.&lt;/p&gt;

&lt;p&gt;I decided to pull out my secret weapon. I don't remember what it's called or where I learned it. I think it's somewhat of a cross between a technique that Neil Gaiman uses to get himself to write and something I read in Deep Work.&lt;/p&gt;

&lt;p&gt;It works like this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You are not allowed to think about anything besides the problem for X minutes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;So I did that and came up with perhaps the most &lt;strong&gt;brilliant&lt;/strong&gt; idea I have ever had in my life.&lt;/p&gt;


&lt;h3&gt;
  
  
  A local TV station!
&lt;/h3&gt;

&lt;p&gt;Not unlike the famed Simpson's monorail, building and managing a local TV station would solve ALL these problems and more!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The kids would love it. What kid wouldn't like the idea of creating movies that their friends can watch on TV?
&lt;/li&gt;
&lt;li&gt;It would be super-educational for the kids. They would get to learn some of the most essential skills that aren't taught in schools.
&lt;/li&gt;
&lt;li&gt;It would be educational for me. Video and video streaming are obviously essential to TV. I would get to do what I was &lt;strong&gt;supposed&lt;/strong&gt; to be doing for work, and my kids would let me do it because they want to see themselves on TV already.
&lt;/li&gt;
&lt;li&gt;It would provide &lt;strong&gt;meaning.&lt;/strong&gt; We would be helping our community. We are a very close community and spend lots of time in each other's houses. This would be a way to bring the community together and help people feel less lonely.
&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  How I did it (and how you can too!)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1. Onboarding.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I called a family meeting.&lt;/p&gt;

&lt;p&gt;More accurately, I said, really loudly:&lt;/p&gt;

&lt;p&gt;"Ditsa, Libi, and Yaffa come here, I have something to tell you."&lt;/p&gt;

&lt;p&gt;When no one responded, I tried again:&lt;/p&gt;

&lt;p&gt;"Ditsa, Libi, and Yaffa come here, I have something to tell you &lt;strong&gt;that you are going to like!&lt;/strong&gt;"&lt;/p&gt;

&lt;p&gt;Now I had an audience 😄.&lt;/p&gt;

&lt;p&gt;I shared my idea with them, and they were &lt;strong&gt;TOTALLY&lt;/strong&gt; down.&lt;/p&gt;

&lt;p&gt;"Dad, you are telling us that if we put together a play, you can get it on TV??"&lt;/p&gt;

&lt;p&gt;Before I could even explain that I would first need to BUILD the TV station, they had run off, eager to begin planning for their TV debut.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There could be no turning back now.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2. Creating the station.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I needed to get a website up quickly. I wanted to build something that would be fast to create, lightweight, easy to explain to the kids, and easy to replicate.&lt;/p&gt;

&lt;p&gt;I think I succeeded!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"icon"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://via.placeholder.com/70x70"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://andybrewer.github.io/mvp/mvp.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"My description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Local TV&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&amp;lt;u&amp;gt;&lt;/span&gt;Local&lt;span class="nt"&gt;&amp;lt;i&amp;gt;&lt;/span&gt;TV&lt;span class="nt"&gt;&amp;lt;/i&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Brought to you by
        &lt;span class="nt"&gt;&amp;lt;mark&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://api.video"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;api.video&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/mark&amp;gt;&lt;/span&gt;!
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position:relative;padding-top:56.25%;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- replace src with the embed code you get from api.video --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://embed.api.video/live/li4G2ooxtZEgsgdsgdsgdsHn7WxQtYJuHn3"&lt;/span&gt;
                    &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position:absolute;top:0;left:0;width:100%;height:100%;"&lt;/span&gt;
                    &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yup! That's the &lt;strong&gt;ENTIRE&lt;/strong&gt; website. You can literally just copy/paste that into a text file, save it with a .html suffix, and you're done (well, with the TV website UI at least)!&lt;/p&gt;

&lt;p&gt;You can see what this looks like in action at &lt;a href="http://mishktv.com"&gt;mishktv.com&lt;/a&gt;. It's dead air much of the time, but you just may get lucky and catch a live performance!  &lt;/p&gt;

&lt;p&gt;You can also play around with this&lt;a href="https://codepen.io/yitzi/pen/ExjBMdE"&gt;on Codepen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are actually following along and implementing your own TV station, I'd recommend forking &lt;a href="https://github.com/apivideo/LocalTV"&gt;the repo&lt;/a&gt; from Github. If you don't know what that means, don't worry, all you need is the code block above saved in a .html file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3. Set up an account with a video API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To stream, we need a platform that can receive that broadcast and play it back live to a broad and distributed audience (your neighbors).&lt;/p&gt;

&lt;p&gt;I chose to use &lt;a href="https://api.video/"&gt;api.video&lt;/a&gt;, and if you want to follow along, then it would be easiest to use them as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visit &lt;a href="https://api.video"&gt;api.video&lt;/a&gt; (duh!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
            &lt;br&gt;
            &lt;br&gt;
            &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v_QeGwSr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_b55bf40e308917e6e2af370791c1943b_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--v_QeGwSr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_b55bf40e308917e6e2af370791c1943b_800.PNG" width="800" height="466"&gt;&lt;/a&gt;&lt;br&gt;
        &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the big blue "Sign up for free" button.&lt;/li&gt;
&lt;li&gt;You know how to sign up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
            &lt;br&gt;
            &lt;br&gt;
            &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k2gUV5BR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_31f9e6004c5f1e7a5e2808801ba5e08c_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--k2gUV5BR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_31f9e6004c5f1e7a5e2808801ba5e08c_800.PNG" width="578" height="176"&gt;&lt;/a&gt;&lt;br&gt;
        &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select "Sandbox" and then click "My live stream."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
            &lt;br&gt;
            &lt;br&gt;
            &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uSrPWJrr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_61dd9892e702b6172e947dda78830bcf_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--uSrPWJrr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_61dd9892e702b6172e947dda78830bcf_800.PNG" width="589" height="280"&gt;&lt;/a&gt;&lt;br&gt;
        &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name your stream. You can change this later.&lt;/li&gt;
&lt;li&gt;Hit "Save Livestream"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
            &lt;br&gt;
            &lt;br&gt;
            &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lbp6OPH0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_399267764f46097f487a96c8b3625f8f_800.PNG" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lbp6OPH0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/Capture_399267764f46097f487a96c8b3625f8f_800.PNG" width="775" height="371"&gt;&lt;/a&gt;&lt;br&gt;Leave this window open
        &lt;/p&gt;

&lt;p&gt;🎉🎉🎉Congrats!! You have successfully created a live stream!!🎉🎉🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4. Update index.html&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remember the .html file from earlier? Now that you have created a live stream we just need to make a small update to configure it to display your stream.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clicking on your live stream from the dashboard that you have open on api.video will bring you to a page that looks like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
            &lt;br&gt;
            &lt;br&gt;
            &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KlZ-Togv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/tempsnip_aec15b95d9d8d037ea5a23035d8804fc_1000.png" class="article-body-image-wrapper"&gt;&lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--KlZ-Togv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.storychief.com/account_21166/tempsnip_aec15b95d9d8d037ea5a23035d8804fc_1000.png" width="880" height="595"&gt;&lt;/a&gt;&lt;br&gt;
        &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clicking "Copy link" will copy everything you need to your clipboard.&lt;/li&gt;
&lt;li&gt;Look for the "src" attribute inside the iframe (there is only one).&lt;/li&gt;
&lt;li&gt;Replace the placeholder link with the link you just copied.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my case, it now looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://embed.api.video/live/li4j6xLydSACIaLDWoznxSgX"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position:absolute;top:0;left:0;width:100%;height:100%;"&lt;/span&gt; &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Save the file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congrats!! You are now &lt;strong&gt;finished&lt;/strong&gt; building your TV station!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5. Going live&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your station is done, but no one is going to be able to watch it if it remains on your computer. You must deploy it to a static web host.&lt;/p&gt;

&lt;p&gt;If you have never deployed a static site before, I recommend trying out &lt;a href="https://tiiny.host"&gt;tiiny.host&lt;/a&gt; (not an affiliate link, just the simplest I've found).&lt;/p&gt;

&lt;p&gt;My fingers are getting sore from all this typing, so watch this video to see how it's done:&lt;/p&gt;

&lt;p&gt;Now all that's left to do is to share the link and get famous!  &lt;/p&gt;

&lt;p&gt;Well, almost...&lt;/p&gt;

&lt;p&gt;You do still need to plan and create content for your TV show and broadcast it to your live stream.&lt;/p&gt;

&lt;p&gt;Don't worry if you have never used broadcasting software before. It's not difficult to learn.&lt;/p&gt;

&lt;p&gt;To start, I'd recommend reading "&lt;a href="https://github.com/apivideo/LocalTV#to-start-a-stream"&gt;To Start a Stream&lt;/a&gt;." and "&lt;a href="http://meow.noopkat.com/lessons-from-one-year-of-streaming-on-twitch/"&gt;Lessons from my first year of live coding on Twitch&lt;/a&gt;."&lt;/p&gt;




&lt;p&gt;If you haven't noticed, I did not quite accomplish what I set out to do. I never did get around to explaining what I was doing in the bear suit.  &lt;/p&gt;

&lt;p&gt;But this post is definitely done.&lt;/p&gt;

&lt;p&gt;I guess you'll have to stay tuned for &lt;strong&gt;Part 2 😀 See ya then!&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Principles of Developer Focused Design</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Sun, 24 Nov 2019 14:22:33 +0000</pubDate>
      <link>https://dev.to/yitzi/principles-of-developer-focused-design-1h0l</link>
      <guid>https://dev.to/yitzi/principles-of-developer-focused-design-1h0l</guid>
      <description>&lt;p&gt;To understand how to “encourage” developer adoption of an SDK, API, or any other developer-focused product, we need to understand what attracts them and what pushes them away.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The only assumption you can make regarding your developer audience is that they are human beings, even that is just a heuristic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developers, like most humans, like things fast and easy. They want to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the info they need quickly.&lt;/li&gt;
&lt;li&gt;Be able to read and understand it quickly.&lt;/li&gt;
&lt;li&gt;Get it working rapidly with a minimum of hiccups.&lt;/li&gt;
&lt;li&gt;Feel that the technology they are integrating into their app is current and robust.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To that end I’d recommend:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A. Setting up a developer site at an independent subdomain.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mixing developer docs with marketing content and other content typically present on a primary site is not a good look and makes it harder for developers to find what they need.&lt;/li&gt;
&lt;li&gt;Developers want to feel that they are learning and integrating relevant tech. The more they hang around on a marketing site to get the info they need, the more they feel like the tech is an afterthought.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;B. Not using Wordpress/Zendesk.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Besides being cluttered and buggy, they can turn off developers because of their association with inferior and old tech.&lt;/li&gt;
&lt;li&gt;I think a static site is perfect for documentation. Static websites are easy and cheap to build and maintain. Most are uncluttered by default, and they are blazing fast.&lt;/li&gt;
&lt;li&gt;As an example, take a look at &lt;a href="https://netflix.github.io/pollyjs/#/quick-start"&gt;Polly.js’s documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://yitzi.dev"&gt;yitzi.dev&lt;/a&gt; is another excellent static documentation site demonstrating a clean non-cluttered UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If members have to scroll past large banners or find useful information among static content, that’s bad. Minimize the static material to show the latest activity. Deliver the maximum value for the minimum amount of effort. -&lt;a href="https://www.feverbee.com/community-design-principles"&gt;Richard Millington&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;C. As much as possible, code samples and documentation should be current and consistent.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In any case, it should be clear which one is the single “source of truth.”&lt;/li&gt;
&lt;li&gt;Another advantage of using a static site for documentation is that updating a version number in a data file can trigger a rebuild of the entire website in seconds, causing an update of that variable across the site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;D. Instructions and Examples should be simple and relatable.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tell a story.&lt;/li&gt;
&lt;li&gt;Developers won’t be upset if you explain things clearly, but they will get angry if you make them feel dumb.&lt;/li&gt;
&lt;li&gt;Help the developer understand the use case and motivation for the different features of your software.&lt;/li&gt;
&lt;li&gt;See here for an &lt;a href="https://medium.com/@YitziG/how-i-became-an-indie-developer-b35ed0954b1a?source=friends_link&amp;amp;sk=f63a0b5dd367d14d253ac500df898b52"&gt;&lt;strong&gt;article I wrote&lt;/strong&gt;&lt;/a&gt; giving motivation for mobile attribution integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;E. Provide an IRC channel where developers can get help from other developers in real-time.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There will always be issues, and developers need to feel like there is somewhere they can turn.&lt;/li&gt;
&lt;li&gt;Discord is excellent, and Slack is OK, I guess.&lt;/li&gt;
&lt;li&gt;At the start, there will need to be an investment of employee time. If done right as the community gets involved in the channel, company employees will be able to step back.&lt;/li&gt;
&lt;li&gt;Before setting up your channel, see if there is already a developer community IRC where this channel would be appropriate. Going to your community is a lot easier and more productive than trying to drag them to you.&lt;/li&gt;
&lt;li&gt;Every single page of the developer website should have a prominent link to the channel. It should never be more than one click away.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developing software is frequently frustrating and almost always takes more time than the developer imagined it would. This is true for code newbies as well as for the most talented developers who are in love with coding. If you make life easier for developers, they will love you.&lt;/p&gt;

&lt;p&gt;Simple, really.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>ux</category>
      <category>devrel</category>
      <category>documentation</category>
    </item>
    <item>
      <title>How I Became an Indie Developer.</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Tue, 19 Nov 2019 14:24:45 +0000</pubDate>
      <link>https://dev.to/yitzi/how-i-became-an-indie-developer-42og</link>
      <guid>https://dev.to/yitzi/how-i-became-an-indie-developer-42og</guid>
      <description>&lt;p&gt;I couldn’t believe it.&lt;/p&gt;

&lt;p&gt;My new app, “Virtree,” was doing amazingly well on the play store. It had been at the top of both “Product Hunt” and “Show HN” for weeks. In under one month since launch, people had downloaded it more than 100,000 times.&lt;/p&gt;

&lt;p&gt;At six months with more than 500,000 installs, I was going to have to shut it down.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hi, I’m Yitzi.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jMI7l19B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A7iEak2Ix9uUmNEPlG34elQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jMI7l19B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A7iEak2Ix9uUmNEPlG34elQ.png" alt="" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I build apps for a living. Mostly for large corporations that pay me an excellent take-home salary and then go on to make exponentially more than that from my hard work.&lt;/p&gt;

&lt;p&gt;I’m good at what I do. I know that because the play store data is publicly available. I can see how much people love my apps by the number of times they download them, and by the reviews they leave (I read every one). It irritates me that my work is not published under my name but rather under the name of the corporation. They wouldn’t know an SDK from an APK!&lt;/p&gt;

&lt;p&gt;It’s been my dream to support myself as an Indie Developer. I would be able to make the products I’ve always dreamed of ( I have a list with more than 100 ideas on it! ). Owning my creations would be the cherry on top (&lt;a href="https://twitter.com/taylorswift13/status/1195123215657508867"&gt;ask Taylor Swift&lt;/a&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  My plan.
&lt;/h4&gt;

&lt;p&gt;I’m not naive. I know that building an amazing and beautiful app is not enough. I’m not happy about that, but I do need to take it into account.&lt;/p&gt;

&lt;p&gt;It’s a chicken and egg problem. The best apps rank well and show up on the front page of the Appstore. To show up there, however, the app already needs to be getting some traction.&lt;/p&gt;

&lt;p&gt;At companies where I’d worked, I noticed this:&lt;/p&gt;

&lt;p&gt;Regardless of how useful and necessary, no manager authorized an app launch without an advertising budget and plan.&lt;/p&gt;

&lt;p&gt;It works like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Advertising campaigns led to non-organic installs.&lt;/li&gt;
&lt;li&gt;Installs make the app rank and become more visible.&lt;/li&gt;
&lt;li&gt;Mobile users will discover the app on their own and download it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By saving up and pitching friends and relatives, I was able to set up a decent sized advertising budget. I figured I had enough for six months. I knew that my app was good and filling a real need. I was sure it would be profitable by then.&lt;/p&gt;

&lt;h4&gt;
  
  
  The app.
&lt;/h4&gt;

&lt;p&gt;I decided to begin my career as an indie developer with “Virtree.”&lt;/p&gt;

&lt;p&gt;Virtree is an app that allows you to “plant” trees on Virtree’s proprietary blockchain. Currently, we only support binary trees with Red-Black trees coming soon.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/EmTHa4UlCUY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The trees can be planted in memoriam of a loved one or as a special gift for a spouse or fiance.&lt;/p&gt;

&lt;p&gt;Forest fires will never destroy these trees. Neither will Lyme disease threaten them. Visiting your tree is as easy as whipping out your phone.&lt;/p&gt;

&lt;p&gt;From my friends’ reactions to the app, I knew I had a winner. I was sure that if I only got some eyes on it, the rest would take care of itself.&lt;/p&gt;

&lt;h4&gt;
  
  
  The launch.
&lt;/h4&gt;

&lt;p&gt;Click. Click. Click.&lt;/p&gt;

&lt;p&gt;It had been 24 hours since I had deployed my signed APK, and it was still in “Pending Publication” limbo.&lt;/p&gt;

&lt;p&gt;I was refreshing the screen compulsively and not answering calls or doing much of anything for that matter. When the status finally changed to “Published,” it didn’t even register until I had refreshed the page at least another five times.&lt;/p&gt;

&lt;p&gt;I called up all my friends and insisted they download my app with me on the line. I felt a chemical rush each time I saw the install count go up. This is the life I thought to myself. It’s this easy. Why didn’t I have the guts to try this earlier?&lt;/p&gt;

&lt;p&gt;I began posting on Facebook groups and sharing on Twitter. Downloads and installs spiked. I started fantasizing about new Apple products and trips to Hawaii.&lt;/p&gt;

&lt;p&gt;Then I hit 42 downloads. “Hit” is a very accurate description. It was as if I had hit something substantial. A wall or something. Nothing I did could budge the needle.&lt;/p&gt;

&lt;p&gt;I had exhausted myself. A vacation was what I needed. I packed up my gear and headed for a week off the grid at Yellowstone.&lt;/p&gt;

&lt;p&gt;When I got back home, I raced to my computer with my loaded backpack still on. 41. Yikes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ads. Ads. Ads.
&lt;/h4&gt;

&lt;p&gt;I wasn’t that worried because I had been planning all along to do some advertising. It’s just that part of me wasn’t ready to admit that. I had a deep inner belief that advertising my app would be “cheating.” I wanted to make it on my own. Now, faced with the prospect of needing to ask for my job back, I was ready.&lt;/p&gt;

&lt;p&gt;“kualitychepeinstalls.onion is fantastic,” said my friend Greg. Greg has made a ton of money investing in Bitcoin and considers himself qualified to dispense advice as frequently as a soda machine dispenses sugar.&lt;/p&gt;

&lt;p&gt;Five dollars and thirty minutes later, I had 5,000 fresh installs. I couldn’t believe it! I went back to “kualitychepeinstalls.onion” and transferred another forty-five dollars. Sure enough, in under an hour, I had another 45,000 installs.&lt;/p&gt;

&lt;p&gt;I began paying for Facebook and Google ads as well. “kualitychepeinstalls” was great, but the whole “.onion” thing was weirding me out. Plus, I figured three is better than one and could only serve to diversify my reach.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AoSN7zlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/1%2A_whGZPGvX0ziZ7uSEjzveg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AoSN7zlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/500/1%2A_whGZPGvX0ziZ7uSEjzveg.png" alt="" width="500" height="614"&gt;&lt;/a&gt;I needed more of this!&lt;/p&gt;

&lt;h4&gt;
  
  
  One month later.
&lt;/h4&gt;

&lt;p&gt;!%$#@%@!!&lt;/p&gt;

&lt;p&gt;I’ve got 100,000 installs. I have no idea if those installs are organic or if they came from Facebook, Google, or KualityChepe.&lt;/p&gt;

&lt;p&gt;KualityChepe claims they are all from them, and I better transfer another fifty thousand, or else.&lt;/p&gt;

&lt;p&gt;Even worse than that issue is this one:&lt;/p&gt;

&lt;p&gt;Only three trees were purchased, two of them by the same user!&lt;/p&gt;

&lt;p&gt;If this continues, I’d be finished.&lt;/p&gt;

&lt;h4&gt;
  
  
  Five months after that.
&lt;/h4&gt;

&lt;p&gt;I’m finished.&lt;/p&gt;

&lt;h4&gt;
  
  
  A ray of hope.
&lt;/h4&gt;

&lt;p&gt;Driving home from WeWork for the last time with all my stuff in the trunk, I was about to flip on some depressing Country when “Indie Hackers” starts playing. Funny because I don’t remember that I was listening to it on the way to work.&lt;/p&gt;

&lt;p&gt;The host is interviewing some indie dev who “made it.” The developer (I can’t remember who it was) described a situation similar to mine and began talking about how mobile attribution completely turned around his ad spend and strategy. I was having the same problem as he was! Many installs but very few quality ones. I made a mental note to google “mobile attribution” when I got home.&lt;/p&gt;

&lt;h4&gt;
  
  
  A new lease.
&lt;/h4&gt;

&lt;p&gt;I had high hopes for mobile attribution. From what I understood, this technology would help me prove how many clicks were coming from each network, so I would not get overcharged.&lt;/p&gt;

&lt;p&gt;More importantly, it would allow me to take a scientific approach to my advertising. I would be able to understand where I was getting the most value and which networks I should drop.&lt;/p&gt;

&lt;h4&gt;
  
  
  A new plan.
&lt;/h4&gt;

&lt;p&gt;I did a second fundraising round, and by psychologically pressuring and manipulating my friends and family, I was able to raise enough funds for two additional months of advertising. I also received promises of extra funding if I could prove that the advertising was working to increase bottom-line revenue.&lt;/p&gt;

&lt;p&gt;Appsflyer seemed to be the platform of choice for three reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They integrate with over 2,000 ad networks making it easier for me to get started quickly.&lt;/li&gt;
&lt;li&gt;They own the market and therefore have a kind of “network effect” advantage. AppsFlyer can more accurately and frequently correctly identify and attribute a user.&lt;/li&gt;
&lt;li&gt;I have a friend who works there, and she sent me links to their Github, where they have sample integrations, as well as to their “quick-start” guide.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I planned to go through their Github and install guide and then integrate their SDK into my app. Once that was done, I would advertise my app in a wide variety of places. After a month, I would carefully analyze the data and become much smarter. I would understand my users, where they are coming from, and what are they doing inside my app.&lt;/p&gt;

&lt;p&gt;I would then advertise for a second month based on the outcome of that analysis.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion.
&lt;/h4&gt;

&lt;p&gt;Well, I don’t want to give it all away now. Suffice it to say that I’m still an indie developer, I always integrate Appsflyer into every software product I build, and Virtree never made me any money.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;Disclaimer: Very little of this is true; it belongs to the genre of “developer fiction.” I'm not an indie developer and have no desire to be. I'm happy to work at a great company that respects my autonomy and pays me fairly.&lt;/p&gt;

&lt;p&gt;P.S. If I would leave my current job, it would only be to write, speak, build cool projects, and teach tech.&lt;/p&gt;

&lt;p&gt;P.P.S. If you know a company that is looking for a creative thinker with years of software experience for a role where I'd get to learn, write, build cool projects, and teach tech. Hit me up!&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>devfiction</category>
    </item>
    <item>
      <title>Someone wrote a URL to HTML/CSS/JS Decoder.</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Sun, 07 Jul 2019 19:01:00 +0000</pubDate>
      <link>https://dev.to/yitzi/someone-wrote-a-url-to-html-css-js-decoder-1lci</link>
      <guid>https://dev.to/yitzi/someone-wrote-a-url-to-html-css-js-decoder-1lci</guid>
      <description>&lt;p&gt;This website does not exist! There is no HTML or JS hosted anywhere. All the necesarry code is hidden in this URL!&lt;/p&gt;

&lt;p&gt;The main page of this site decodes all that follows the # into HTML, CSS, and JS!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jstrieb.github.io/urlpages/#JTBBJTNDIURPQ1RZUEUlMjBodG1sJTNFJTBBJTNDaGVhZCUzRSUwQSUzQ3N0eWxlJTNFJTBBJTBBJTNDJTJGc3R5bGUlM0UlMEElM0NzY3JpcHQlMjB0eXBlJTNEJTIydGV4dCUyRmphdmFzY3JpcHQlMjIlM0UlMEElMkYqJTIwVGhpcyUyMGxpYnJhcnklMjBpcyUyMHJlbGVhc2VkJTIwdW5kZXIlMjB0aGUlMjBNSVQlMjBsaWNlbnNlJTJDJTIwc2VlJTIwaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGdGVobm9rdiUyRnBpY29qcyUyMColMkYlMEFwaWNvJTIwJTNEJTIwJTdCJTdEJTBBJTBBcGljby51bnBhY2tfY2FzY2FkZSUyMCUzRCUyMGZ1bmN0aW9uKGJ5dGVzKSUwQSU3QiUwQSUwOSUyRiUyRiUwQSUwOWNvbnN0JTIwZHZpZXclMjAlM0QlMjBuZXclMjBEYXRhVmlldyhuZXclMjBBcnJheUJ1ZmZlcig0KSklM0IlMEElMDklMkYqJTBBJTA5JTA5d2UlMjBza2lwJTIwdGhlJTIwZmlyc3QlMjA4JTIwYnl0ZXMlMjBvZiUyMHRoZSUyMGNhc2NhZGUlMjBmaWxlJTBBJTA5JTA5KGNhc2NhZGUlMjB2ZXJzaW9uJTIwbnVtYmVyJTIwYW5kJTIwc29tZSUyMGRhdGElMjB1c2VkJTIwZHVyaW5nJTIwdGhlJTIwbGVhcm5pbmclMjBwcm9jZXNzKSUwQSUwOSolMkYlMEElMDlsZXQlMjBwJTIwJTNEJTIwOCUzQiUwQSUwOSUyRiolMEElMDklMDlyZWFkJTIwdGhlJTIwZGVwdGglMjAoc2l6ZSklMjBvZiUyMGVhY2glMjB0cmVlJTIwZmlyc3QlM0ElMjBhJTIwMzItYml0JTIwc2lnbmVkJTIwaW50ZWdlciUwQSUwOSolMkYlMEElMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDljb25zdCUyMHRkZXB0aCUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUwQSUwOSUyRiolMEElMDklMDluZXh0JTJDJTIwcmVhZCUyMHRoZSUyMG51bWJlciUyMG9mJTIwdHJlZXMlMjBpbiUyMHRoZSUyMGNhc2NhZGUlM0ElMjBhbm90aGVyJTIwMzItYml0JTIwc2lnbmVkJTIwaW50ZWdlciUwQSUwOSolMkYlMEElMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDljb25zdCUyMG50cmVlcyUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUwQSUwOSUyRiolMEElMDklMDlyZWFkJTIwdGhlJTIwYWN0dWFsJTIwdHJlZXMlMjBhbmQlMjBjYXNjYWRlJTIwdGhyZXNob2xkcyUwQSUwOSolMkYlMEElMDljb25zdCUyMHRjb2Rlc19scyUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOWNvbnN0JTIwdHByZWRzX2xzJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTA5Y29uc3QlMjB0aHJlc2hfbHMlMjAlM0QlMjAlNUIlNUQlM0IlMEElMDlmb3IobGV0JTIwdCUzRDAlM0IlMjB0JTNDbnRyZWVzJTNCJTIwJTJCJTJCdCklMEElMDklN0IlMEElMDklMDklMkYlMkYlMjByZWFkJTIwdGhlJTIwYmluYXJ5JTIwdGVzdHMlMjBwbGFjZWQlMjBpbiUyMGludGVybmFsJTIwdHJlZSUyMG5vZGVzJTBBJTA5JTA5QXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkodGNvZGVzX2xzJTJDJTIwJTVCMCUyQyUyMDAlMkMlMjAwJTJDJTIwMCU1RCklM0IlMEElMDklMDlBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0Y29kZXNfbHMlMkMlMjBieXRlcy5zbGljZShwJTJDJTIwcCUyQjQqTWF0aC5wb3coMiUyQyUyMHRkZXB0aCktNCkpJTNCJTBBJTA5JTA5cCUyMCUzRCUyMHAlMjAlMkIlMjA0Kk1hdGgucG93KDIlMkMlMjB0ZGVwdGgpLTQlM0IlMEElMDklMDklMkYlMkYlMjByZWFkJTIwdGhlJTIwcHJlZGljdGlvbiUyMGluJTIwdGhlJTIwbGVhZiUyMG5vZGVzJTIwb2YlMjB0aGUlMjB0cmVlJTBBJTA5JTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ01hdGgucG93KDIlMkMlMjB0ZGVwdGgpJTNCJTIwJTJCJTJCaSklMEElMDklMDklN0IlMEElMDklMDklMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDklMDklMDl0cHJlZHNfbHMucHVzaChkdmlldy5nZXRGbG9hdDMyKDAlMkMlMjB0cnVlKSklM0IlMEElMDklMDklMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQlM0IlMEElMDklMDklN0QlMEElMDklMDklMkYlMkYlMjByZWFkJTIwdGhlJTIwdGhyZXNob2xkJTBBJTA5JTA5ZHZpZXcuc2V0VWludDgoMCUyQyUyMGJ5dGVzJTVCcCUyQjAlNUQpJTJDJTIwZHZpZXcuc2V0VWludDgoMSUyQyUyMGJ5dGVzJTVCcCUyQjElNUQpJTJDJTIwZHZpZXcuc2V0VWludDgoMiUyQyUyMGJ5dGVzJTVCcCUyQjIlNUQpJTJDJTIwZHZpZXcuc2V0VWludDgoMyUyQyUyMGJ5dGVzJTVCcCUyQjMlNUQpJTNCJTBBJTA5JTA5dGhyZXNoX2xzLnB1c2goZHZpZXcuZ2V0RmxvYXQzMigwJTJDJTIwdHJ1ZSkpJTNCJTBBJTA5JTA5cCUyMCUzRCUyMHAlMjAlMkIlMjA0JTNCJTBBJTA5JTdEJTBBJTA5Y29uc3QlMjB0Y29kZXMlMjAlM0QlMjBuZXclMjBJbnQ4QXJyYXkodGNvZGVzX2xzKSUzQiUwQSUwOWNvbnN0JTIwdHByZWRzJTIwJTNEJTIwbmV3JTIwRmxvYXQzMkFycmF5KHRwcmVkc19scyklM0IlMEElMDljb25zdCUyMHRocmVzaCUyMCUzRCUyMG5ldyUyMEZsb2F0MzJBcnJheSh0aHJlc2hfbHMpJTNCJTBBJTA5JTJGKiUwQSUwOSUwOWNvbnN0cnVjdCUyMHRoZSUyMGNsYXNzaWZpY2F0aW9uJTIwZnVuY3Rpb24lMjBmcm9tJTIwdGhlJTIwcmVhZCUyMGRhdGElMEElMDkqJTJGJTBBJTA5ZnVuY3Rpb24lMjBjbGFzc2lmeV9yZWdpb24ociUyQyUyMGMlMkMlMjBzJTJDJTIwcGl4ZWxzJTJDJTIwbGRpbSklMEElMDklN0IlMEElMDklMDklMjByJTIwJTNEJTIwMjU2KnIlM0IlMEElMDklMDklMjBjJTIwJTNEJTIwMjU2KmMlM0IlMEElMDklMDklMjBsZXQlMjByb290JTIwJTNEJTIwMCUzQiUwQSUwOSUwOSUyMGxldCUyMG8lMjAlM0QlMjAwLjAlM0IlMEElMDklMDklMjBjb25zdCUyMHBvdzJ0ZGVwdGglMjAlM0QlMjBNYXRoLnBvdygyJTJDJTIwdGRlcHRoKSUyMCUzRSUzRSUyMDAlM0IlMjAlMkYlMkYlMjAnJTNFJTNFMCclMjB0cmFuc2Zvcm1zJTIwdGhpcyUyMG51bWJlciUyMHRvJTIwaW50JTBBJTBBJTA5JTA5JTIwZm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ250cmVlcyUzQiUyMCUyQiUyQmkpJTBBJTA5JTA5JTIwJTdCJTBBJTA5JTA5JTA5aWR4JTIwJTNEJTIwMSUzQiUwQSUwOSUwOSUwOWZvcihsZXQlMjBqJTNEMCUzQiUyMGolM0N0ZGVwdGglM0IlMjAlMkIlMkJqKSUwQSUwOSUwOSUwOSUwOSUyRiUyRiUyMHdlJTIwdXNlJTIwJyUzRSUzRSUyMDgnJTIwaGVyZSUyMHRvJTIwcGVyZm9ybSUyMGFuJTIwaW50ZWdlciUyMGRpdmlzaW9uJTNBJTIwdGhpcyUyMHNlZW1zJTIwaW1wb3J0YW50JTIwZm9yJTIwcGVyZm9ybWFuY2UlMEElMDklMDklMDklMDlpZHglMjAlM0QlMjAyKmlkeCUyMCUyQiUyMChwaXhlbHMlNUIoKHIlMkJ0Y29kZXMlNUJyb290JTIwJTJCJTIwNCppZHglMjAlMkIlMjAwJTVEKnMpJTIwJTNFJTNFJTIwOCkqbGRpbSUyQigoYyUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDElNUQqcyklMjAlM0UlM0UlMjA4KSU1RCUzQyUzRHBpeGVscyU1QigociUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDIlNUQqcyklMjAlM0UlM0UlMjA4KSpsZGltJTJCKChjJTJCdGNvZGVzJTVCcm9vdCUyMCUyQiUyMDQqaWR4JTIwJTJCJTIwMyU1RCpzKSUyMCUzRSUzRSUyMDgpJTVEKSUzQiUwQSUwQSUwOSUwOSUwOSUyMG8lMjAlM0QlMjBvJTIwJTJCJTIwdHByZWRzJTVCcG93MnRkZXB0aCppJTIwJTJCJTIwaWR4LXBvdzJ0ZGVwdGglNUQlM0IlMEElMEElMDklMDklMDklMjBpZihvJTNDJTNEdGhyZXNoJTVCaSU1RCklMEElMDklMDklMDklMDklMjByZXR1cm4lMjAtMSUzQiUwQSUwQSUwOSUwOSUwOSUyMHJvb3QlMjAlMkIlM0QlMjA0KnBvdzJ0ZGVwdGglM0IlMEElMDklMDklN0QlMEElMDklMDlyZXR1cm4lMjBvJTIwLSUyMHRocmVzaCU1Qm50cmVlcy0xJTVEJTNCJTBBJTA5JTdEJTBBJTA5JTJGKiUwQSUwOSUwOXdlJ3JlJTIwZG9uZSUwQSUwOSolMkYlMEElMDlyZXR1cm4lMjBjbGFzc2lmeV9yZWdpb24lM0IlMEElN0QlMEElMEFwaWNvLnJ1bl9jYXNjYWRlJTIwJTNEJTIwZnVuY3Rpb24oaW1hZ2UlMkMlMjBjbGFzc2lmeV9yZWdpb24lMkMlMjBwYXJhbXMpJTBBJTdCJTBBJTA5Y29uc3QlMjBwaXhlbHMlMjAlM0QlMjBpbWFnZS5waXhlbHMlM0IlMEElMDljb25zdCUyMG5yb3dzJTIwJTNEJTIwaW1hZ2UubnJvd3MlM0IlMEElMDljb25zdCUyMG5jb2xzJTIwJTNEJTIwaW1hZ2UubmNvbHMlM0IlMEElMDljb25zdCUyMGxkaW0lMjAlM0QlMjBpbWFnZS5sZGltJTNCJTBBJTBBJTA5Y29uc3QlMjBzaGlmdGZhY3RvciUyMCUzRCUyMHBhcmFtcy5zaGlmdGZhY3RvciUzQiUwQSUwOWNvbnN0JTIwbWluc2l6ZSUyMCUzRCUyMHBhcmFtcy5taW5zaXplJTNCJTBBJTA5Y29uc3QlMjBtYXhzaXplJTIwJTNEJTIwcGFyYW1zLm1heHNpemUlM0IlMEElMDljb25zdCUyMHNjYWxlZmFjdG9yJTIwJTNEJTIwcGFyYW1zLnNjYWxlZmFjdG9yJTNCJTBBJTBBJTA5bGV0JTIwc2NhbGUlMjAlM0QlMjBtaW5zaXplJTNCJTBBJTA5Y29uc3QlMjBkZXRlY3Rpb25zJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTBBJTA5d2hpbGUoc2NhbGUlM0MlM0RtYXhzaXplKSUwQSUwOSU3QiUwQSUwOSUwOWNvbnN0JTIwc3RlcCUyMCUzRCUyME1hdGgubWF4KHNoaWZ0ZmFjdG9yKnNjYWxlJTJDJTIwMSklMjAlM0UlM0UlMjAwJTNCJTIwJTJGJTJGJTIwJyUzRSUzRTAnJTIwdHJhbnNmb3JtcyUyMHRoaXMlMjBudW1iZXIlMjB0byUyMGludCUwQSUwOSUwOWNvbnN0JTIwb2Zmc2V0JTIwJTNEJTIwKHNjYWxlJTJGMiUyMCUyQiUyMDEpJTIwJTNFJTNFJTIwMCUzQiUwQSUwQSUwOSUwOWZvcihsZXQlMjByJTNEb2Zmc2V0JTNCJTIwciUzQyUzRG5yb3dzLW9mZnNldCUzQiUyMHIlMkIlM0RzdGVwKSUwQSUwOSUwOSUwOWZvcihsZXQlMjBjJTNEb2Zmc2V0JTNCJTIwYyUzQyUzRG5jb2xzLW9mZnNldCUzQiUyMGMlMkIlM0RzdGVwKSUwQSUwOSUwOSUwOSU3QiUwQSUwOSUwOSUwOSUwOWNvbnN0JTIwcSUyMCUzRCUyMGNsYXNzaWZ5X3JlZ2lvbihyJTJDJTIwYyUyQyUyMHNjYWxlJTJDJTIwcGl4ZWxzJTJDJTIwbGRpbSklM0IlMEElMDklMDklMDklMDlpZiUyMChxJTIwJTNFJTIwMC4wKSUwQSUwOSUwOSUwOSUwOSUwOWRldGVjdGlvbnMucHVzaCglNUJyJTJDJTIwYyUyQyUyMHNjYWxlJTJDJTIwcSU1RCklM0IlMEElMDklMDklMDklN0QlMEElMDklMDklMEElMDklMDlzY2FsZSUyMCUzRCUyMHNjYWxlKnNjYWxlZmFjdG9yJTNCJTBBJTA5JTdEJTBBJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwZGV0ZWN0aW9ucyUzQiUwQSU3RCUwQSUwQXBpY28uY2x1c3Rlcl9kZXRlY3Rpb25zJTIwJTNEJTIwZnVuY3Rpb24oZGV0cyUyQyUyMGlvdXRocmVzaG9sZCklMEElN0IlMEElMDklMkYqJTBBJTA5JTA5c29ydCUyMGRldGVjdGlvbnMlMjBieSUyMHRoZWlyJTIwc2NvcmUlMEElMDkqJTJGJTBBJTA5ZGV0cyUyMCUzRCUyMGRldHMuc29ydChmdW5jdGlvbihhJTJDJTIwYiklMjAlN0IlMEElMDklMDlyZXR1cm4lMjBiJTVCMyU1RCUyMC0lMjBhJTVCMyU1RCUzQiUwQSUwOSU3RCklM0IlMEElMDklMkYqJTBBJTA5JTA5dGhpcyUyMGhlbHBlciUyMGZ1bmN0aW9uJTIwY2FsY3VsYXRlcyUyMHRoZSUyMGludGVyc2VjdGlvbiUyMG92ZXIlMjB1bmlvbiUyMGZvciUyMHR3byUyMGRldGVjdGlvbnMlMEElMDkqJTJGJTBBJTA5ZnVuY3Rpb24lMjBjYWxjdWxhdGVfaW91KGRldDElMkMlMjBkZXQyKSUwQSUwOSU3QiUwQSUwOSUwOSUyRiUyRiUyMHVucGFjayUyMHRoZSUyMHBvc2l0aW9uJTIwYW5kJTIwc2l6ZSUyMG9mJTIwZWFjaCUyMGRldGVjdGlvbiUwQSUwOSUwOWNvbnN0JTIwcjElM0RkZXQxJTVCMCU1RCUyQyUyMGMxJTNEZGV0MSU1QjElNUQlMkMlMjBzMSUzRGRldDElNUIyJTVEJTNCJTBBJTA5JTA5Y29uc3QlMjByMiUzRGRldDIlNUIwJTVEJTJDJTIwYzIlM0RkZXQyJTVCMSU1RCUyQyUyMHMyJTNEZGV0MiU1QjIlNUQlM0IlMEElMDklMDklMkYlMkYlMjBjYWxjdWxhdGUlMjBkZXRlY3Rpb24lMjBvdmVybGFwJTIwaW4lMjBlYWNoJTIwZGltZW5zaW9uJTBBJTA5JTA5Y29uc3QlMjBvdmVyciUyMCUzRCUyME1hdGgubWF4KDAlMkMlMjBNYXRoLm1pbihyMSUyQnMxJTJGMiUyQyUyMHIyJTJCczIlMkYyKSUyMC0lMjBNYXRoLm1heChyMS1zMSUyRjIlMkMlMjByMi1zMiUyRjIpKSUzQiUwQSUwOSUwOWNvbnN0JTIwb3ZlcmMlMjAlM0QlMjBNYXRoLm1heCgwJTJDJTIwTWF0aC5taW4oYzElMkJzMSUyRjIlMkMlMjBjMiUyQnMyJTJGMiklMjAtJTIwTWF0aC5tYXgoYzEtczElMkYyJTJDJTIwYzItczIlMkYyKSklM0IlMEElMDklMDklMkYlMkYlMjBjYWxjdWxhdGUlMjBhbmQlMjByZXR1cm4lMjBJb1UlMEElMDklMDlyZXR1cm4lMjBvdmVycipvdmVyYyUyRihzMSpzMSUyQnMyKnMyLW92ZXJyKm92ZXJjKSUzQiUwQSUwOSU3RCUwQSUwOSUyRiolMEElMDklMDlkbyUyMGNsdXN0ZXJpbmclMjB0aHJvdWdoJTIwbm9uLW1heGltdW0lMjBzdXBwcmVzc2lvbiUwQSUwOSolMkYlMEElMDljb25zdCUyMGFzc2lnbm1lbnRzJTIwJTNEJTIwbmV3JTIwQXJyYXkoZGV0cy5sZW5ndGgpLmZpbGwoMCklM0IlMEElMDljb25zdCUyMGNsdXN0ZXJzJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ2RldHMubGVuZ3RoJTNCJTIwJTJCJTJCaSklMEElMDklN0IlMEElMDklMDklMkYlMkYlMjBpcyUyMHRoaXMlMjBkZXRlY3Rpb24lMjBhc3NpZ25lZCUyMHRvJTIwYSUyMGNsdXN0ZXIlM0YlMEElMDklMDlpZihhc3NpZ25tZW50cyU1QmklNUQlM0QlM0QwKSUwQSUwOSUwOSU3QiUwQSUwOSUwOSUwOSUyRiUyRiUyMGl0JTIwaXMlMjBub3QlM0ElMEElMDklMDklMDklMkYlMkYlMjBub3clMjB3ZSUyMG1ha2UlMjBhJTIwY2x1c3RlciUyMG91dCUyMG9mJTIwaXQlMjBhbmQlMjBzZWUlMjB3aGV0aGVyJTIwc29tZSUyMG90aGVyJTIwZGV0ZWN0aW9ucyUyMGJlbG9uZyUyMHRvJTIwaXQlMEElMDklMDklMDlsZXQlMjByJTNEMC4wJTJDJTIwYyUzRDAuMCUyQyUyMHMlM0QwLjAlMkMlMjBxJTNEMC4wJTJDJTIwbiUzRDAlM0IlMEElMDklMDklMDlmb3IobGV0JTIwaiUzRGklM0IlMjBqJTNDZGV0cy5sZW5ndGglM0IlMjAlMkIlMkJqKSUwQSUwOSUwOSUwOSUwOWlmKGNhbGN1bGF0ZV9pb3UoZGV0cyU1QmklNUQlMkMlMjBkZXRzJTVCaiU1RCklM0Vpb3V0aHJlc2hvbGQpJTBBJTA5JTA5JTA5JTA5JTdCJTBBJTA5JTA5JTA5JTA5JTA5YXNzaWdubWVudHMlNUJqJTVEJTIwJTNEJTIwMSUzQiUwQSUwOSUwOSUwOSUwOSUwOXIlMjAlM0QlMjByJTIwJTJCJTIwZGV0cyU1QmolNUQlNUIwJTVEJTNCJTBBJTA5JTA5JTA5JTA5JTA5YyUyMCUzRCUyMGMlMjAlMkIlMjBkZXRzJTVCaiU1RCU1QjElNUQlM0IlMEElMDklMDklMDklMDklMDlzJTIwJTNEJTIwcyUyMCUyQiUyMGRldHMlNUJqJTVEJTVCMiU1RCUzQiUwQSUwOSUwOSUwOSUwOSUwOXElMjAlM0QlMjBxJTIwJTJCJTIwZGV0cyU1QmolNUQlNUIzJTVEJTNCJTBBJTA5JTA5JTA5JTA5JTA5biUyMCUzRCUyMG4lMjAlMkIlMjAxJTNCJTBBJTA5JTA5JTA5JTA5JTdEJTBBJTA5JTA5JTA5JTJGJTJGJTIwbWFrZSUyMGElMjBjbHVzdGVyJTIwcmVwcmVzZW50YXRpdmUlMEElMDklMDklMDljbHVzdGVycy5wdXNoKCU1QnIlMkZuJTJDJTIwYyUyRm4lMkMlMjBzJTJGbiUyQyUyMHElNUQpJTNCJTBBJTA5JTA5JTdEJTBBJTA5JTdEJTBBJTBBJTA5cmV0dXJuJTIwY2x1c3RlcnMlM0IlMEElN0QlMEElMEFwaWNvLmluc3RhbnRpYXRlX2RldGVjdGlvbl9tZW1vcnklMjAlM0QlMjBmdW5jdGlvbihzaXplKSUwQSU3QiUwQSUwOSUyRiolMEElMDklMDlpbml0aWFsaXplJTIwYSUyMGNpcmN1bGFyJTIwYnVmZmVyJTIwb2YlMjAlNjBzaXplJTYwJTIwZWxlbWVudHMlMEElMDkqJTJGJTBBJTA5bGV0JTIwbiUyMCUzRCUyMDAlM0IlMEElMDljb25zdCUyMG1lbW9yeSUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOWZvcihsZXQlMjBpJTNEMCUzQiUyMGklM0NzaXplJTNCJTIwJTJCJTJCaSklMEElMDklMDltZW1vcnkucHVzaCglNUIlNUQpJTNCJTBBJTA5JTJGKiUwQSUwOSUwOWJ1aWxkJTIwYSUyMGZ1bmN0aW9uJTIwdGhhdCUzQSUwQSUwOSUwOSgxKSUyMGluc2VydHMlMjB0aGUlMjBjdXJyZW50JTIwZnJhbWUncyUyMGRldGVjdGlvbnMlMjBpbnRvJTIwdGhlJTIwYnVmZmVyJTNCJTBBJTA5JTA5KDIpJTIwbWVyZ2VzJTIwYWxsJTIwZGV0ZWN0aW9ucyUyMGZyb20lMjB0aGUlMjBsYXN0JTIwJTYwc2l6ZSU2MCUyMGZyYW1lcyUyMGFuZCUyMHJldHVybnMlMjB0aGVtJTBBJTA5KiUyRiUwQSUwOWZ1bmN0aW9uJTIwdXBkYXRlX21lbW9yeShkZXRzKSUwQSUwOSU3QiUwQSUwOSUwOW1lbW9yeSU1Qm4lNUQlMjAlM0QlMjBkZXRzJTNCJTBBJTA5JTA5biUyMCUzRCUyMChuJTJCMSklMjVtZW1vcnkubGVuZ3RoJTNCJTBBJTA5JTA5ZGV0cyUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOSUwOWZvcihpJTNEMCUzQiUyMGklM0NtZW1vcnkubGVuZ3RoJTNCJTIwJTJCJTJCaSklMEElMDklMDklMDlkZXRzJTIwJTNEJTIwZGV0cy5jb25jYXQobWVtb3J5JTVCaSU1RCklM0IlMEElMDklMDklMkYlMkYlMEElMDklMDlyZXR1cm4lMjBkZXRzJTNCJTBBJTA5JTdEJTBBJTA5JTJGKiUwQSUwOSUwOXdlJ3JlJTIwZG9uZSUwQSUwOSolMkYlMEElMDlyZXR1cm4lMjB1cGRhdGVfbWVtb3J5JTNCJTBBJTdEJTBBJTBBJTJGKiUyMFRoaXMlMjBsaWJyYXJ5JTIwaXMlMjByZWxlYXNlZCUyMHVuZGVyJTIwdGhlJTIwTUlUJTIwbGljZW5zZSUyQyUyMGNvbnRhY3QlMjAlNDB0ZWhub2t2JTIwZm9yJTIwbW9yZSUyMGRldGFpbHMlMjAqJTJGJTBBbHBsb2MlMjAlM0QlMjAlN0IlN0QlMEElMEFscGxvYy51bnBhY2tfbG9jYWxpemVyJTIwJTNEJTIwZnVuY3Rpb24oYnl0ZXMpJTBBJTdCJTBBJTA5JTJGJTJGJTBBJTA5Y29uc3QlMjBkdmlldyUyMCUzRCUyMG5ldyUyMERhdGFWaWV3KG5ldyUyMEFycmF5QnVmZmVyKDQpKSUzQiUwQSUwOWxldCUyMHAlMjAlM0QlMjAwJTNCJTBBJTA5JTJGKiUwQSUwOSUwOXJlYWQlMjB0aGUlMjBudW1iZXIlMjBvZiUyMHN0YWdlcyUyQyUyMHNjYWxlJTIwbXVsdGlwbGllciUyMChhcHBsaWVkJTIwYWZ0ZXIlMjBlYWNoJTIwc3RhZ2UpJTJDJTBBJTA5JTA5bnVtYmVyJTIwb2YlMjB0cmVlcyUyMHBlciUyMHN0YWdlJTIwYW5kJTIwZGVwdGglMjBvZiUyMGVhY2glMjB0cmVlJTBBJTA5KiUyRiUwQSUwOWR2aWV3LnNldFVpbnQ4KDAlMkMlMjBieXRlcyU1QnAlMkIwJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDElMkMlMjBieXRlcyU1QnAlMkIxJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDIlMkMlMjBieXRlcyU1QnAlMkIyJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDMlMkMlMjBieXRlcyU1QnAlMkIzJTVEKSUzQiUwQSUwOWNvbnN0JTIwbnN0YWdlcyUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUzQiUwQSUwOWR2aWV3LnNldFVpbnQ4KDAlMkMlMjBieXRlcyU1QnAlMkIwJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDElMkMlMjBieXRlcyU1QnAlMkIxJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDIlMkMlMjBieXRlcyU1QnAlMkIyJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDMlMkMlMjBieXRlcyU1QnAlMkIzJTVEKSUzQiUwQSUwOWNvbnN0JTIwc2NhbGVtdWwlMjAlM0QlMjBkdmlldy5nZXRGbG9hdDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUzQiUwQSUwOWR2aWV3LnNldFVpbnQ4KDAlMkMlMjBieXRlcyU1QnAlMkIwJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDElMkMlMjBieXRlcyU1QnAlMkIxJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDIlMkMlMjBieXRlcyU1QnAlMkIyJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDMlMkMlMjBieXRlcyU1QnAlMkIzJTVEKSUzQiUwQSUwOWNvbnN0JTIwbnRyZWVzcGVyc3RhZ2UlMjAlM0QlMjBkdmlldy5nZXRJbnQzMigwJTJDJTIwdHJ1ZSklM0IlMEElMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQlM0IlMEElMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDljb25zdCUyMHRkZXB0aCUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUzQiUwQSUwOSUyRiolMEElMDklMDl1bnBhY2slMjB0aGUlMjB0cmVlcyUwQSUwOSolMkYlMEElMDljb25zdCUyMHRjb2Rlc19scyUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOWNvbnN0JTIwdHByZWRzX2xzJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ25zdGFnZXMlM0IlMjAlMkIlMkJpKSUwQSUwOSU3QiUwQSUwOSUwOSUyRiUyRiUyMHJlYWQlMjB0aGUlMjB0cmVlcyUyMGZvciUyMHRoaXMlMjBzdGFnZSUwQSUwOSUwOWZvcihsZXQlMjBqJTNEMCUzQiUyMGolM0NudHJlZXNwZXJzdGFnZSUzQiUyMCUyQiUyQmopJTBBJTA5JTA5JTdCJTBBJTA5JTA5JTA5JTJGJTJGJTIwYmluYXJ5JTIwdGVzdHMlMjAod2UlMjBjYW4lMjByZWFkJTIwYWxsJTIwb2YlMjB0aGVtJTIwYXQlMjBvbmNlKSUwQSUwOSUwOSUwOUFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRjb2Rlc19scyUyQyUyMGJ5dGVzLnNsaWNlKHAlMkMlMjBwJTJCNCpNYXRoLnBvdygyJTJDJTIwdGRlcHRoKS00KSklM0IlMEElMDklMDklMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQqTWF0aC5wb3coMiUyQyUyMHRkZXB0aCktNCUzQiUwQSUwOSUwOSUwOSUyRiUyRiUyMHJlYWQlMjB0aGUlMjBwcmVkaWN0aW9uJTIwaW4lMjB0aGUlMjBsZWFmJTIwbm9kZXMlMjBvZiUyMHRoZSUyMHRyZWUlMEElMDklMDklMDlmb3IobGV0JTIwayUzRDAlM0IlMjBrJTNDTWF0aC5wb3coMiUyQyUyMHRkZXB0aCklM0IlMjAlMkIlMkJrKSUwQSUwOSUwOSUwOSUwOWZvcihsZXQlMjBsJTNEMCUzQiUyMGwlM0MyJTNCJTIwJTJCJTJCbCklMEElMDklMDklMDklMDklN0IlMEElMDklMDklMDklMDklMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDklMDklMDklMDklMDl0cHJlZHNfbHMucHVzaChkdmlldy5nZXRGbG9hdDMyKDAlMkMlMjB0cnVlKSklM0IlMEElMDklMDklMDklMDklMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQlM0IlMEElMDklMDklMDklMDklN0QlMEElMDklMDklN0QlMEElMDklN0QlMEElMDljb25zdCUyMHRjb2RlcyUyMCUzRCUyMG5ldyUyMEludDhBcnJheSh0Y29kZXNfbHMpJTNCJTBBJTA5Y29uc3QlMjB0cHJlZHMlMjAlM0QlMjBuZXclMjBGbG9hdDMyQXJyYXkodHByZWRzX2xzKSUzQiUwQSUwOSUyRiolMEElMDklMDljb25zdHJ1Y3QlMjB0aGUlMjBsb2NhdGlvbiUyMGVzdGltYXRvbiUyMGZ1bmN0aW9uJTBBJTA5KiUyRiUwQSUwOWZ1bmN0aW9uJTIwbG9jX2Z1bihyJTJDJTIwYyUyQyUyMHMlMkMlMjBwaXhlbHMlMkMlMjBucm93cyUyQyUyMG5jb2xzJTJDJTIwbGRpbSklMEElMDklN0IlMEElMDklMDlsZXQlMjByb290JTIwJTNEJTIwMCUzQiUwQSUwOSUwOWNvbnN0JTIwcG93MnRkZXB0aCUyMCUzRCUyME1hdGgucG93KDIlMkMlMjB0ZGVwdGgpJTIwJTNFJTNFJTIwMCUzQiUyMCUyRiUyRiUyMCclM0UlM0UwJyUyMHRyYW5zZm9ybXMlMjB0aGlzJTIwbnVtYmVyJTIwdG8lMjBpbnQlMEElMEElMDklMDlmb3IobGV0JTIwaSUzRDAlM0IlMjBpJTNDbnN0YWdlcyUzQiUyMCUyQiUyQmkpJTBBJTA5JTA5JTdCJTBBJTA5JTA5JTA5bGV0JTIwZHIlM0QwLjAlMkMlMjBkYyUzRDAuMCUzQiUwQSUwQSUwOSUwOSUwOWZvcihsZXQlMjBqJTNEMCUzQiUyMGolM0NudHJlZXNwZXJzdGFnZSUzQiUyMCUyQiUyQmopJTBBJTA5JTA5JTA5JTdCJTBBJTA5JTA5JTA5JTA5bGV0JTIwaWR4JTIwJTNEJTIwMCUzQiUwQSUwOSUwOSUwOSUwOWZvcih2YXIlMjBrJTNEMCUzQiUyMGslM0N0ZGVwdGglM0IlMjAlMkIlMkJrKSUwQSUwOSUwOSUwOSUwOSU3QiUwQSUwOSUwOSUwOSUwOSUwOWNvbnN0JTIwcjElMjAlM0QlMjBNYXRoLm1pbihucm93cy0xJTJDJTIwTWF0aC5tYXgoMCUyQyUyMCgyNTYqciUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDAlNUQqcyklM0UlM0U4KSklM0IlMEElMDklMDklMDklMDklMDljb25zdCUyMGMxJTIwJTNEJTIwTWF0aC5taW4obmNvbHMtMSUyQyUyME1hdGgubWF4KDAlMkMlMjAoMjU2KmMlMkJ0Y29kZXMlNUJyb290JTIwJTJCJTIwNCppZHglMjAlMkIlMjAxJTVEKnMpJTNFJTNFOCkpJTNCJTBBJTA5JTA5JTA5JTA5JTA5Y29uc3QlMjByMiUyMCUzRCUyME1hdGgubWluKG5yb3dzLTElMkMlMjBNYXRoLm1heCgwJTJDJTIwKDI1NipyJTJCdGNvZGVzJTVCcm9vdCUyMCUyQiUyMDQqaWR4JTIwJTJCJTIwMiU1RCpzKSUzRSUzRTgpKSUzQiUwQSUwOSUwOSUwOSUwOSUwOWNvbnN0JTIwYzIlMjAlM0QlMjBNYXRoLm1pbihuY29scy0xJTJDJTIwTWF0aC5tYXgoMCUyQyUyMCgyNTYqYyUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDMlNUQqcyklM0UlM0U4KSklM0IlMEElMEElMDklMDklMDklMDklMDlpZHglMjAlM0QlMjAyKmlkeCUyMCUyQiUyMDElMjAlMkIlMjAocGl4ZWxzJTVCcjEqbGRpbSUyQmMxJTVEJTIwJTNFJTIwcGl4ZWxzJTVCcjIqbGRpbSUyQmMyJTVEKSUwQSUwOSUwOSUwOSUwOSU3RCUwQSUwQSUwOSUwOSUwOSUwOWNvbnN0JTIwbHV0aWR4JTIwJTNEJTIwMioobnRyZWVzcGVyc3RhZ2UqcG93MnRkZXB0aCppJTIwJTJCJTIwcG93MnRkZXB0aCpqJTIwJTJCJTIwaWR4JTIwLSUyMChwb3cydGRlcHRoJTIwLSUyMDEpKSUwQSUwOSUwOSUwOSUwOWRyJTIwJTJCJTNEJTIwdHByZWRzJTVCbHV0aWR4JTIwJTJCJTIwMCU1RCUzQiUwQSUwOSUwOSUwOSUwOWRjJTIwJTJCJTNEJTIwdHByZWRzJTVCbHV0aWR4JTIwJTJCJTIwMSU1RCUzQiUwQSUwQSUwOSUwOSUwOSUwOXJvb3QlMjAlMkIlM0QlMjA0KnBvdzJ0ZGVwdGglMjAtJTIwNCUzQiUwQSUwOSUwOSUwOSU3RCUwQSUwQSUwOSUwOSUwOXIlMjAlM0QlMjByJTIwJTJCJTIwZHIqcyUzQiUwQSUwOSUwOSUwOWMlMjAlM0QlMjBjJTIwJTJCJTIwZGMqcyUzQiUwQSUwQSUwOSUwOSUwOXMlMjAlM0QlMjBzKnNjYWxlbXVsJTNCJTBBJTA5JTA5JTdEJTBBJTBBJTA5JTA5cmV0dXJuJTIwJTVCciUyQyUyMGMlNUQlM0IlMEElMDklN0QlMEElMDklMkYqJTBBJTA5JTA5dGhpcyUyMGZ1bmN0aW9uJTIwYXBwbGllcyUyMHJhbmRvbSUyMHBlcnR1cmJhdGlvbnMlMjB0byUyMHRoZSUyMGRlZmF1bHQlMjByZWN0YW5nbGUlMjAociUyQyUyMGMlMkMlMjBzKSUwQSUwOSolMkYlMEElMDlmdW5jdGlvbiUyMGxvY19mdW5fd2l0aF9wZXJ0dXJicyhyJTJDJTIwYyUyQyUyMHMlMkMlMjBucGVydHVyYnMlMkMlMjBpbWFnZSklMEElMDklN0IlMEElMDklMDljb25zdCUyMHJvd3MlM0QlNUIlNUQlMkMlMjBjb2xzJTNEJTVCJTVEJTNCJTBBJTBBJTA5JTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ25wZXJ0dXJicyUzQiUyMCUyQiUyQmkpJTBBJTA5JTA5JTdCJTBBJTA5JTA5JTA5Y29uc3QlMjBfcyUyMCUzRCUyMHMqKDAuOTI1JTIwJTJCJTIwMC4xNSpNYXRoLnJhbmRvbSgpKSUzQiUwQSUwOSUwOSUwOWxldCUyMF9yJTIwJTNEJTIwciUyMCUyQiUyMHMqMC4xNSooMC41JTIwLSUyME1hdGgucmFuZG9tKCkpJTNCJTBBJTA5JTA5JTA5bGV0JTIwX2MlMjAlM0QlMjBjJTIwJTJCJTIwcyowLjE1KigwLjUlMjAtJTIwTWF0aC5yYW5kb20oKSklM0IlMEElMEElMDklMDklMDklNUJfciUyQyUyMF9jJTVEJTIwJTNEJTIwbG9jX2Z1bihfciUyQyUyMF9jJTJDJTIwX3MlMkMlMjBpbWFnZS5waXhlbHMlMkMlMjBpbWFnZS5ucm93cyUyQyUyMGltYWdlLm5jb2xzJTJDJTIwaW1hZ2UubGRpbSklMEElMEElMDklMDklMDlyb3dzLnB1c2goX3IpJTBBJTA5JTA5JTA5Y29scy5wdXNoKF9jKSUwQSUwOSUwOSU3RCUwQSUwQSUwOSUwOSUyRiUyRiUyMHJldHVybiUyMHRoZSUyMG1lZGlhbiUyMGFsb25nJTIwZWFjaCUyMGF4aXMlMEElMDklMDlyb3dzLnNvcnQoKSUwQSUwOSUwOWNvbHMuc29ydCgpJTBBJTBBJTA5JTA5cmV0dXJuJTIwJTVCcm93cyU1Qk1hdGgucm91bmQobnBlcnR1cmJzJTJGMiklNUQlMkMlMjBjb2xzJTVCTWF0aC5yb3VuZChucGVydHVyYnMlMkYyKSU1RCU1RCUzQiUwQSUwOSU3RCUwQSUwOSUyRiolMEElMDklMDl3ZSdyZSUyMGRvbmUlMEElMDkqJTJGJTBBJTA5cmV0dXJuJTIwbG9jX2Z1bl93aXRoX3BlcnR1cmJzJTNCJTBBJTdEJTBBJTBBJTJGKiUwQSUwOVRoaXMlMjBjb2RlJTIwd2FzJTIwdGFrZW4lMjBmcm9tJTIwaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGY2JyYW5kb2xpbm8lMkZjYW12YXMlMjBhbmQlMjBtb2RpZmllZCUyMHRvJTIwc3VpdCUyMG91ciUyMG5lZWRzJTBBKiUyRiUwQSUyRiolMEFDb3B5cmlnaHQlMjAoYyklMjAyMDEyJTIwQ2xhdWRpbyUyMEJyYW5kb2xpbm8lMEElMEFQZXJtaXNzaW9uJTIwaXMlMjBoZXJlYnklMjBncmFudGVkJTJDJTIwZnJlZSUyMG9mJTIwY2hhcmdlJTJDJTIwdG8lMjBhbnklMjBwZXJzb24lMjBvYnRhaW5pbmclMjBhJTIwY29weSUyMG9mJTIwdGhpcyUyMHNvZnR3YXJlJTIwYW5kJTIwYXNzb2NpYXRlZCUyMGRvY3VtZW50YXRpb24lMjBmaWxlcyUyMCh0aGUlMjAlMjJTb2Z0d2FyZSUyMiklMkMlMjB0byUyMGRlYWwlMjBpbiUyMHRoZSUyMFNvZnR3YXJlJTIwd2l0aG91dCUyMHJlc3RyaWN0aW9uJTJDJTIwaW5jbHVkaW5nJTIwd2l0aG91dCUyMGxpbWl0YXRpb24lMjB0aGUlMjByaWdodHMlMjB0byUyMHVzZSUyQyUyMGNvcHklMkMlMjBtb2RpZnklMkMlMjBtZXJnZSUyQyUyMHB1Ymxpc2glMkMlMjBkaXN0cmlidXRlJTJDJTIwc3VibGljZW5zZSUyQyUyMGFuZCUyRm9yJTIwc2VsbCUyMGNvcGllcyUyMG9mJTIwdGhlJTIwU29mdHdhcmUlMkMlMjBhbmQlMjB0byUyMHBlcm1pdCUyMHBlcnNvbnMlMjB0byUyMHdob20lMjB0aGUlMjBTb2Z0d2FyZSUyMGlzJTIwZnVybmlzaGVkJTIwdG8lMjBkbyUyMHNvJTJDJTIwc3ViamVjdCUyMHRvJTIwdGhlJTIwZm9sbG93aW5nJTIwY29uZGl0aW9ucyUzQSUwQSUwQVRoZSUyMGFib3ZlJTIwY29weXJpZ2h0JTIwbm90aWNlJTIwYW5kJTIwdGhpcyUyMHBlcm1pc3Npb24lMjBub3RpY2UlMjBzaGFsbCUyMGJlJTIwaW5jbHVkZWQlMjBpbiUyMGFsbCUyMGNvcGllcyUyMG9yJTIwc3Vic3RhbnRpYWwlMjBwb3J0aW9ucyUyMG9mJTIwdGhlJTIwU29mdHdhcmUuJTBBJTBBVEhFJTIwU09GVFdBUkUlMjBJUyUyMFBST1ZJREVEJTIwJTIyQVMlMjBJUyUyMiUyQyUyMFdJVEhPVVQlMjBXQVJSQU5UWSUyME9GJTIwQU5ZJTIwS0lORCUyQyUyMEVYUFJFU1MlMjBPUiUyMElNUExJRUQlMkMlMjBJTkNMVURJTkclMjBCVVQlMjBOT1QlMjBMSU1JVEVEJTIwVE8lMjBUSEUlMjBXQVJSQU5USUVTJTIwT0YlMjBNRVJDSEFOVEFCSUxJVFklMkMlMjBGSVRORVNTJTIwRk9SJTIwQSUyMFBBUlRJQ1VMQVIlMjBQVVJQT1NFJTIwQU5EJTIwTk9OSU5GUklOR0VNRU5ULiUyMElOJTIwTk8lMjBFVkVOVCUyMFNIQUxMJTIwVEhFJTIwQVVUSE9SUyUyME9SJTIwQ09QWVJJR0hUJTIwSE9MREVSUyUyMEJFJTIwTElBQkxFJTIwRk9SJTIwQU5ZJTIwQ0xBSU0lMkMlMjBEQU1BR0VTJTIwT1IlMjBPVEhFUiUyMExJQUJJTElUWSUyQyUyMFdIRVRIRVIlMjBJTiUyMEFOJTIwQUNUSU9OJTIwT0YlMjBDT05UUkFDVCUyQyUyMFRPUlQlMjBPUiUyME9USEVSV0lTRSUyQyUyMEFSSVNJTkclMjBGUk9NJTJDJTIwT1VUJTIwT0YlMjBPUiUyMElOJTIwQ09OTkVDVElPTiUyMFdJVEglMjBUSEUlMjBTT0ZUV0FSRSUyME9SJTIwVEhFJTIwVVNFJTIwT1IlMjBPVEhFUiUyMERFQUxJTkdTJTIwSU4lMjBUSEUlMjBTT0ZUV0FSRS4lMEEqJTJGJTBBJTJGJTJGJTIwVGhlJTIwZnVuY3Rpb24lMjB0YWtlcyUyMGElMjBjYW52YXMlMjBjb250ZXh0JTIwYW5kJTIwYSUyMCU2MGRyYXdGdW5jJTYwJTIwZnVuY3Rpb24uJTBBJTJGJTJGJTIwJTYwZHJhd0Z1bmMlNjAlMjByZWNlaXZlcyUyMHR3byUyMHBhcmFtZXRlcnMlMkMlMjB0aGUlMjB2aWRlbyUyMGFuZCUyMHRoZSUyMHRpbWUlMjBzaW5jZSUwQSUyRiUyRiUyMHRoZSUyMGxhc3QlMjB0aW1lJTIwaXQlMjB3YXMlMjBjYWxsZWQuJTBBZnVuY3Rpb24lMjBjYW12YXMoY3R4JTJDJTIwY2FsbGJhY2spJTIwJTdCJTBBJTIwJTIwdmFyJTIwc2VsZiUyMCUzRCUyMHRoaXMlMEElMjAlMjB0aGlzLmN0eCUyMCUzRCUyMGN0eCUwQSUyMCUyMHRoaXMuY2FsbGJhY2slMjAlM0QlMjBjYWxsYmFjayUwQSUwQSUyMCUyMCUyRiUyRiUyMFdlJTIwY2FuJ3QlMjAlNjBuZXclMjBWaWRlbygpJTYwJTIweWV0JTJDJTIwc28lMjB3ZSdsbCUyMHJlc29ydCUyMHRvJTIwdGhlJTIwdmludGFnZSUwQSUyMCUyMCUyRiUyRiUyMCUyMmhpZGRlbiUyMGRpdiUyMiUyMGhhY2slMjBmb3IlMjBkeW5hbWljJTIwbG9hZGluZy4lMEElMjAlMjB2YXIlMjBzdHJlYW1Db250YWluZXIlMjAlM0QlMjBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSUwQSUyMCUyMHRoaXMudmlkZW8lMjAlM0QlMjBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpJTBBJTBBJTIwJTIwJTJGJTJGJTIwSWYlMjB3ZSUyMGRvbid0JTIwZG8lMjB0aGlzJTJDJTIwdGhlJTIwc3RyZWFtJTIwd2lsbCUyMG5vdCUyMGJlJTIwcGxheWVkLiUwQSUyMCUyMCUyRiUyRiUyMEJ5JTIwdGhlJTIwd2F5JTJDJTIwdGhlJTIwcGxheSUyMGFuZCUyMHBhdXNlJTIwY29udHJvbHMlMjB3b3JrJTIwYXMlMjB1c3VhbCUyMCUwQSUyMCUyMCUyRiUyRiUyMGZvciUyMHN0cmVhbWVkJTIwdmlkZW9zLiUwQSUyMCUyMHRoaXMudmlkZW8uc2V0QXR0cmlidXRlKCdhdXRvcGxheSclMkMlMjAnMScpJTBBJTIwJTIwdGhpcy52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJyUyQyUyMCcxJyklMjAlMkYlMkYlMjBpbXBvcnRhbnQlMjBmb3IlMjBpUGhvbmVzJTBBJTBBJTIwJTIwJTJGJTJGJTIwVGhlJTIwdmlkZW8lMjBzaG91bGQlMjBmaWxsJTIwb3V0JTIwYWxsJTIwb2YlMjB0aGUlMjBjYW52YXMlMEElMjAlMjB0aGlzLnZpZGVvLnNldEF0dHJpYnV0ZSgnd2lkdGgnJTJDJTIwMSklMEElMjAlMjB0aGlzLnZpZGVvLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyUyQyUyMDEpJTBBJTBBJTIwJTIwc3RyZWFtQ29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMudmlkZW8pJTBBJTIwJTIwZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzdHJlYW1Db250YWluZXIpJTBBJTBBJTIwJTIwJTJGJTJGJTIwVGhlJTIwY2FsbGJhY2slMjBoYXBwZW5zJTIwd2hlbiUyMHdlJTIwYXJlJTIwc3RhcnRpbmclMjB0byUyMHN0cmVhbSUyMHRoZSUyMHZpZGVvLiUwQSUyMCUyMG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKCU3QnZpZGVvJTNBJTIwdHJ1ZSUyQyUyMGF1ZGlvJTNBJTIwZmFsc2UlN0QpLnRoZW4oZnVuY3Rpb24oc3RyZWFtKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyRiUyRiUyMFlheSUyQyUyMG5vdyUyMG91ciUyMHdlYmNhbSUyMGlucHV0JTIwaXMlMjB0cmVhdGVkJTIwYXMlMjBhJTIwbm9ybWFsJTIwdmlkZW8lMjBhbmQlMEElMjAlMjAlMjAlMjAlMkYlMkYlMjB3ZSUyMGNhbiUyMHN0YXJ0JTIwaGF2aW5nJTIwZnVuJTBBJTIwJTIwJTIwJTIwc2VsZi52aWRlby5zcmNPYmplY3QlMjAlM0QlMjBzdHJlYW0lMEElMjAlMjAlMjAlMjAlMkYlMkYlMjBMZXQncyUyMHN0YXJ0JTIwZHJhd2luZyUyMHRoZSUyMGNhbnZhcyElMEElMjAlMjAlMjAlMjBzZWxmLnVwZGF0ZSgpJTBBJTIwJTIwJTdEJTJDJTIwZnVuY3Rpb24oZXJyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMHRocm93JTIwZXJyJTBBJTIwJTIwJTdEKSUwQSUwQSUyMCUyMCUyRiUyRiUyMEFzJTIwc29vbiUyMGFzJTIwd2UlMjBjYW4lMjBkcmF3JTIwYSUyMG5ldyUyMGZyYW1lJTIwb24lMjB0aGUlMjBjYW52YXMlMkMlMjB3ZSUyMGNhbGwlMjB0aGUlMjAlNjBkcmF3JTYwJTIwZnVuY3Rpb24lMjAlMEElMjAlMjAlMkYlMkYlMjB3ZSUyMHBhc3NlZCUyMGFzJTIwYSUyMHBhcmFtZXRlci4lMEElMjAlMjB0aGlzLnVwZGF0ZSUyMCUzRCUyMGZ1bmN0aW9uKCklMjAlN0IlMEElMDl2YXIlMjBzZWxmJTIwJTNEJTIwdGhpcyUwQSUyMCUyMCUyMCUyMHZhciUyMGxhc3QlMjAlM0QlMjBEYXRlLm5vdygpJTBBJTIwJTIwJTIwJTIwdmFyJTIwbG9vcCUyMCUzRCUyMGZ1bmN0aW9uKCklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBGb3IlMjBzb21lJTIwZWZmZWN0cyUyQyUyMHlvdSUyMG1pZ2h0JTIwd2FudCUyMHRvJTIwa25vdyUyMGhvdyUyMG11Y2glMjB0aW1lJTIwaXMlMjBwYXNzZWQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBzaW5jZSUyMHRoZSUyMGxhc3QlMjBmcmFtZSUzQiUyMHRoYXQncyUyMHdoeSUyMHdlJTIwcGFzcyUyMGFsb25nJTIwYSUyMERlbHRhJTIwdGltZSUyMCU2MGR0JTYwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwdmFyaWFibGUlMjAoZXhwcmVzc2VkJTIwaW4lMjBtaWxsaXNlY29uZHMpJTBBJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwZHQlMjAlM0QlMjBEYXRlLm5vdygpJTIwLSUyMGxhc3QlMEElMjAlMjAlMjAlMjAlMjAlMjBzZWxmLmNhbGxiYWNrKHNlbGYudmlkZW8lMkMlMjBkdCklMEElMjAlMjAlMjAlMjAlMjAlMjBsYXN0JTIwJTNEJTIwRGF0ZS5ub3coKSUwQSUyMCUyMCUyMCUyMCUyMCUyMHJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKSUyMCUwQSUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMHJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKSUyMCUwQSUyMCUyMCU3RCUyMCUwQSU3RCUwQSUwQSUzQyUyRnNjcmlwdCUzRSUwQSUzQyUyRmhlYWQlM0UlMEElM0Nib2R5JTNFJTBBJTNDIURPQ1RZUEUlMjBodG1sJTNFJTBBJTNDaHRtbCUzRSUwQSUzQ2hlYWQlM0UlMEElMjAlMjAlMjAlMjAlM0NtZXRhJTIwY2hhcnNldCUzRCUyMnV0Zi04JTIyJTNFJTBBJTIwJTIwJTIwJTIwJTNDbWV0YSUyMGh0dHAtZXF1aXYlM0QlMjJYLVVBLUNvbXBhdGlibGUlMjIlMjBjb250ZW50JTNEJTIyY2hyb21lJTNEMSUyMiUzRSUwQSUyMCUyMCUyMCUyMCUzQ3RpdGxlJTNFU3RhciUyMHB1cGlsISUzQyUyRnRpdGxlJTNFJTBBJTIwJTIwJTIwJTIwJTNDc2NyaXB0JTIwc3JjJTNEJTIyY2FtdmFzLmpzJTIyJTNFJTNDJTJGc2NyaXB0JTNFJTBBJTIwJTIwJTIwJTIwJTNDc2NyaXB0JTIwc3JjJTNEJTIyLi4lMkZwaWNvLmpzJTIyJTNFJTNDJTJGc2NyaXB0JTNFJTBBJTIwJTIwJTIwJTIwJTNDc2NyaXB0JTIwc3JjJTNEJTIyLi4lMkZscGxvYy5qcyUyMiUzRSUzQyUyRnNjcmlwdCUzRSUwQSUyMCUyMCUyMCUyMCUzQyEtLSUzQ21ldGElMjBuYW1lJTNEJTIydmlld3BvcnQlMjIlMjBjb250ZW50JTNEJTIyd2lkdGglM0RkZXZpY2Utd2lkdGglMkMlMjBpbml0aWFsLXNjYWxlJTNEMSUyQyUyMHVzZXItc2NhbGFibGUlM0RubyUyMiUzRS0tJTNFJTBBJTNDJTJGaGVhZCUzRSUwQSUzQ3NjcmlwdCUzRSUwQSUyMCUyMCUyMCUyMHZhciUyMGluaXRpYWxpemVkJTIwJTNEJTIwZmFsc2UlM0IlMEElMEElMjAlMjAlMjAlMjBmdW5jdGlvbiUyMGJ1dHRvbl9jYWxsYmFjaygpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGKiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCgwKSUyMGNoZWNrJTIwd2hldGhlciUyMHdlJ3JlJTIwYWxyZWFkeSUyMHJ1bm5pbmclMjBmYWNlJTIwZGV0ZWN0aW9uJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKGluaXRpYWxpemVkKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUzQiUyMCUyRiUyRiUyMGlmJTIweWVzJTJDJTIwdGhlbiUyMGRvJTIwbm90JTIwaW5pdGlhbGl6ZSUyMGV2ZXJ5dGhpbmclMjBhZ2FpbiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoMSklMjBpbml0aWFsaXplJTIwdGhlJTIwcGljby5qcyUyMGZhY2UlMjBkZXRlY3RvciUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMColMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjB1cGRhdGVfbWVtb3J5JTIwJTNEJTIwcGljby5pbnN0YW50aWF0ZV9kZXRlY3Rpb25fbWVtb3J5KDUpJTNCJTIwJTJGJTJGJTIwd2UlMjB3aWxsJTIwdXNlJTIwdGhlJTIwZGV0ZWNpb25zJTIwb2YlMjB0aGUlMjBsYXN0JTIwNSUyMGZyYW1lcyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMGZhY2VmaW5kZXJfY2xhc3NpZnlfcmVnaW9uJTIwJTNEJTIwZnVuY3Rpb24lMjAociUyQyUyMGMlMkMlMjBzJTJDJTIwcGl4ZWxzJTJDJTIwbGRpbSklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAtMS4wJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwY2FzY2FkZXVybCUyMCUzRCUyMCdodHRwcyUzQSUyRiUyRnJhdy5naXRodWJ1c2VyY29udGVudC5jb20lMkZuZW5hZG1hcmt1cyUyRnBpY28lMkZjMmU4MWY5ZDIzY2MxMWQxYTYxMmZkMjFlNGY5ZGUwOTIxYTVkMGQ5JTJGcm50JTJGY2FzY2FkZXMlMkZmYWNlZmluZGVyJyUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZldGNoKGNhc2NhZGV1cmwpLnRoZW4oZnVuY3Rpb24lMjAocmVzcG9uc2UpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVzcG9uc2UuYXJyYXlCdWZmZXIoKS50aGVuKGZ1bmN0aW9uJTIwKGJ1ZmZlciklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjBieXRlcyUyMCUzRCUyMG5ldyUyMEludDhBcnJheShidWZmZXIpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZmFjZWZpbmRlcl9jbGFzc2lmeV9yZWdpb24lMjAlM0QlMjBwaWNvLnVucGFja19jYXNjYWRlKGJ5dGVzKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGNvbnNvbGUubG9nKCcqJTIwZmFjZWZpbmRlciUyMGxvYWRlZCcpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYqJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKDIpJTIwaW5pdGlhbGl6ZSUyMHRoZSUyMGxwbG9jLmpzJTIwbGlicmFyeSUyMHdpdGglMjBhJTIwcHVwaWwlMjBsb2NhbGl6ZXIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAqJTJGJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwZG9fcHVwbG9jJTIwJTNEJTIwZnVuY3Rpb24lMjAociUyQyUyMGMlMkMlMjBzJTJDJTIwbnBlcnR1cmJzJTJDJTIwcGl4ZWxzJTJDJTIwbnJvd3MlMkMlMjBuY29scyUyQyUyMGxkaW0pJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwJTVCLTEuMCUyQyUyMC0xLjAlNUQlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkZ2YXIlMjBwdXBsb2N1cmwlMjAlM0QlMjAnLi4lMkZwdXBsb2MuYmluJyUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMHB1cGxvY3VybCUyMCUzRCUyMCdodHRwcyUzQSUyRiUyRmYwMDIuYmFja2JsYXplYjIuY29tJTJGZmlsZSUyRnRlaG5va3Ytd3d3JTJGcG9zdHMlMkZwdXBsb2Mtd2l0aC10cmVlcyUyRmRlbW8lMkZwdXBsb2MuYmluJyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZldGNoKHB1cGxvY3VybCkudGhlbihmdW5jdGlvbiUyMChyZXNwb25zZSklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXNwb25zZS5hcnJheUJ1ZmZlcigpLnRoZW4oZnVuY3Rpb24lMjAoYnVmZmVyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMGJ5dGVzJTIwJTNEJTIwbmV3JTIwSW50OEFycmF5KGJ1ZmZlciklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkb19wdXBsb2MlMjAlM0QlMjBscGxvYy51bnBhY2tfbG9jYWxpemVyKGJ5dGVzKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGNvbnNvbGUubG9nKCcqJTIwcHVwbG9jJTIwbG9hZGVkJyklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoMyklMjBnZXQlMjB0aGUlMjBkcmF3aW5nJTIwY29udGV4dCUyMG9uJTIwdGhlJTIwY2FudmFzJTIwYW5kJTIwZGVmaW5lJTIwYSUyMGZ1bmN0aW9uJTIwdG8lMjB0cmFuc2Zvcm0lMjBhbiUyMFJHQkElMjBpbWFnZSUyMHRvJTIwZ3JheXNjYWxlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMGN0eCUyMCUzRCUyMGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdjYW52YXMnKSU1QjAlNUQuZ2V0Q29udGV4dCgnMmQnKSUzQiUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZ1bmN0aW9uJTIwcmdiYV90b19ncmF5c2NhbGUocmdiYSUyQyUyMG5yb3dzJTJDJTIwbmNvbHMpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwZ3JheSUyMCUzRCUyMG5ldyUyMFVpbnQ4QXJyYXkobnJvd3MlMjAqJTIwbmNvbHMpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZm9yJTIwKHZhciUyMHIlMjAlM0QlMjAwJTNCJTIwciUyMCUzQyUyMG5yb3dzJTNCJTIwJTJCJTJCciklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBmb3IlMjAodmFyJTIwYyUyMCUzRCUyMDAlM0IlMjBjJTIwJTNDJTIwbmNvbHMlM0IlMjAlMkIlMkJjKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMGdyYXklMjAlM0QlMjAwLjIqcmVkJTIwJTJCJTIwMC43KmdyZWVuJTIwJTJCJTIwMC4xKmJsdWUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBncmF5JTVCciUyMColMjBuY29scyUyMCUyQiUyMGMlNUQlMjAlM0QlMjAoMiUyMColMjByZ2JhJTVCciUyMColMjA0JTIwKiUyMG5jb2xzJTIwJTJCJTIwNCUyMColMjBjJTIwJTJCJTIwMCU1RCUyMCUyQiUyMDclMjAqJTIwcmdiYSU1QnIlMjAqJTIwNCUyMColMjBuY29scyUyMCUyQiUyMDQlMjAqJTIwYyUyMCUyQiUyMDElNUQlMjAlMkIlMjAxJTIwKiUyMHJnYmElNUJyJTIwKiUyMDQlMjAqJTIwbmNvbHMlMjAlMkIlMjA0JTIwKiUyMGMlMjAlMkIlMjAyJTVEKSUyMCUyRiUyMDEwJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwZ3JheSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoNCklMjB0aGlzJTIwZnVuY3Rpb24lMjBpcyUyMGNhbGxlZCUyMGVhY2glMjB0aW1lJTIwYSUyMHZpZGVvJTIwZnJhbWUlMjBiZWNvbWVzJTIwYXZhaWxhYmxlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMHByb2Nlc3NmbiUyMCUzRCUyMGZ1bmN0aW9uJTIwKHZpZGVvJTJDJTIwZHQpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwcmVuZGVyJTIwdGhlJTIwdmlkZW8lMjBmcmFtZSUyMHRvJTIwdGhlJTIwY2FudmFzJTIwZWxlbWVudCUyMGFuZCUyMGV4dHJhY3QlMjBSR0JBJTIwcGl4ZWwlMjBkYXRhJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmRyYXdJbWFnZSh2aWRlbyUyQyUyMDAlMkMlMjAwKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMHJnYmElMjAlM0QlMjBjdHguZ2V0SW1hZ2VEYXRhKDAlMkMlMjAwJTJDJTIwNjQwJTJDJTIwNDgwKS5kYXRhJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwcHJlcGFyZSUyMGlucHV0JTIwdG8lMjAlNjBydW5fY2FzY2FkZSU2MCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGltYWdlJTIwJTNEJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIycGl4ZWxzJTIyJTNBJTIwcmdiYV90b19ncmF5c2NhbGUocmdiYSUyQyUyMDQ4MCUyQyUyMDY0MCklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJucm93cyUyMiUzQSUyMDQ4MCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMm5jb2xzJTIyJTNBJTIwNjQwJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIybGRpbSUyMiUzQSUyMDY0MCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHBhcmFtcyUyMCUzRCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnNoaWZ0ZmFjdG9yJTIyJTNBJTIwMC4xJTJDJTIwJTJGJTJGJTIwbW92ZSUyMHRoZSUyMGRldGVjdGlvbiUyMHdpbmRvdyUyMGJ5JTIwMTAlMjUlMjBvZiUyMGl0cyUyMHNpemUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJtaW5zaXplJTIyJTNBJTIwMTAwJTJDJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwbWluaW11bSUyMHNpemUlMjBvZiUyMGElMjBmYWNlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIybWF4c2l6ZSUyMiUzQSUyMDEwMDAlMkMlMjAlMjAlMjAlMjAlMkYlMkYlMjBtYXhpbXVtJTIwc2l6ZSUyMG9mJTIwYSUyMGZhY2UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJzY2FsZWZhY3RvciUyMiUzQSUyMDEuMSUyMCUyMCUyRiUyRiUyMGZvciUyMG11bHRpc2NhbGUlMjBwcm9jZXNzaW5nJTNBJTIwcmVzaXplJTIwdGhlJTIwZGV0ZWN0aW9uJTIwd2luZG93JTIwYnklMjAxMCUyNSUyMHdoZW4lMjBtb3ZpbmclMjB0byUyMHRoZSUyMGhpZ2hlciUyMHNjYWxlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwcnVuJTIwdGhlJTIwY2FzY2FkZSUyMG92ZXIlMjB0aGUlMjBmcmFtZSUyMGFuZCUyMGNsdXN0ZXIlMjB0aGUlMjBvYnRhaW5lZCUyMGRldGVjdGlvbnMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBkZXRzJTIwaXMlMjBhbiUyMGFycmF5JTIwdGhhdCUyMGNvbnRhaW5zJTIwKHIlMkMlMjBjJTJDJTIwcyUyQyUyMHEpJTIwcXVhZHJ1cGxldHMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjAocmVwcmVzZW50aW5nJTIwcm93JTJDJTIwY29sdW1uJTJDJTIwc2NhbGUlMjBhbmQlMjBkZXRlY3Rpb24lMjBzY29yZSklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkZXRzJTIwJTNEJTIwcGljby5ydW5fY2FzY2FkZShpbWFnZSUyQyUyMGZhY2VmaW5kZXJfY2xhc3NpZnlfcmVnaW9uJTJDJTIwcGFyYW1zKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRldHMlMjAlM0QlMjB1cGRhdGVfbWVtb3J5KGRldHMpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZGV0cyUyMCUzRCUyMHBpY28uY2x1c3Rlcl9kZXRlY3Rpb25zKGRldHMlMkMlMjAwLjIpJTNCJTIwJTJGJTJGJTIwc2V0JTIwSW9VJTIwdGhyZXNob2xkJTIwdG8lMjAwLjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBkcmF3JTIwZGV0ZWN0aW9ucyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZvciUyMChpJTIwJTNEJTIwMCUzQiUyMGklMjAlM0MlMjBkZXRzLmxlbmd0aCUzQiUyMCUyQiUyQmkpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwY2hlY2slMjB0aGUlMjBkZXRlY3Rpb24lMjBzY29yZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMGlmJTIwaXQncyUyMGFib3ZlJTIwdGhlJTIwdGhyZXNob2xkJTJDJTIwZHJhdyUyMGl0JTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwKHRoZSUyMGNvbnN0YW50JTIwNTAuMCUyMGlzJTIwZW1waXJpY2FsJTNBJTIwb3RoZXIlMjBjYXNjYWRlcyUyMG1pZ2h0JTIwcmVxdWlyZSUyMGElMjBkaWZmZXJlbnQlMjBvbmUpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjAoZGV0cyU1QmklNUQlNUIzJTVEJTIwJTNFJTIwNTAuMCklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjByJTJDJTIwYyUyQyUyMHMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguYmVnaW5QYXRoKCklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguYXJjKGRldHMlNUJpJTVEJTVCMSU1RCUyQyUyMGRldHMlNUJpJTVEJTVCMCU1RCUyQyUyMGRldHMlNUJpJTVEJTVCMiU1RCUyRjIlMkMlMjAwJTJDJTIwMipNYXRoLlBJJTJDJTIwZmFsc2UpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwY3R4LmxpbmVXaWR0aCUyMCUzRCUyMDMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguc3Ryb2tlU3R5bGUlMjAlM0QlMjAnYmx1ZSclM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguc3Ryb2tlKCklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBmaW5kJTIwdGhlJTIwZXllJTIwcHVwaWxzJTIwZm9yJTIwZWFjaCUyMGRldGVjdGVkJTIwZmFjZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMHN0YXJ0aW5nJTIwcmVnaW9ucyUyMGZvciUyMGxvY2FsaXphdGlvbiUyMGFyZSUyMGluaXRpYWxpemVkJTIwYmFzZWQlMjBvbiUyMHRoZSUyMGZhY2UlMjBib3VuZGluZyUyMGJveCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMChwYXJhbWV0ZXJzJTIwYXJlJTIwc2V0JTIwZW1waXJpY2FsbHkpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwZmlyc3QlMjBleWUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByJTIwJTNEJTIwZGV0cyU1QmklNUQlNUIwJTVEJTIwLSUyMDAuMDc1JTIwKiUyMGRldHMlNUJpJTVEJTVCMiU1RCUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGMlMjAlM0QlMjBkZXRzJTVCaSU1RCU1QjElNUQlMjAtJTIwMC4xNzUlMjAqJTIwZGV0cyU1QmklNUQlNUIyJTVEJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcyUyMCUzRCUyMDAuMzUlMjAqJTIwZGV0cyU1QmklNUQlNUIyJTVEJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVCciUyQyUyMGMlNUQlMjAlM0QlMjBkb19wdXBsb2MociUyQyUyMGMlMkMlMjBzJTJDJTIwNjMlMkMlMjBpbWFnZSklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMChyJTIwJTNFJTNEJTIwMCUyMCUyNiUyNiUyMGMlMjAlM0UlM0QlMjAwKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5iZWdpblBhdGgoKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5hcmMoYyUyQyUyMHIlMkMlMjAxJTJDJTIwMCUyQyUyMDIlMjAqJTIwTWF0aC5QSSUyQyUyMGZhbHNlKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5saW5lV2lkdGglMjAlM0QlMjAzJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LnN0cm9rZVN0eWxlJTIwJTNEJTIwJ3JlZCclM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBjdHguc3Ryb2tlKCklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBzZWNvbmQlMjBleWUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByJTIwJTNEJTIwZGV0cyU1QmklNUQlNUIwJTVEJTIwLSUyMDAuMDc1JTIwKiUyMGRldHMlNUJpJTVEJTVCMiU1RCUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGMlMjAlM0QlMjBkZXRzJTVCaSU1RCU1QjElNUQlMjAlMkIlMjAwLjE3NSUyMColMjBkZXRzJTVCaSU1RCU1QjIlNUQlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzJTIwJTNEJTIwMC4zNSUyMColMjBkZXRzJTVCaSU1RCU1QjIlNUQlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUJyJTJDJTIwYyU1RCUyMCUzRCUyMGRvX3B1cGxvYyhyJTJDJTIwYyUyQyUyMHMlMkMlMjA2MyUyQyUyMGltYWdlKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKHIlMjAlM0UlM0QlMjAwJTIwJTI2JTI2JTIwYyUyMCUzRSUzRCUyMDApJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmJlZ2luUGF0aCgpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmFyYyhjJTJDJTIwciUyQyUyMDElMkMlMjAwJTJDJTIwMiUyMColMjBNYXRoLlBJJTJDJTIwZmFsc2UpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmxpbmVXaWR0aCUyMCUzRCUyMDMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBjdHguc3Ryb2tlU3R5bGUlMjAlM0QlMjAncmVkJyUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5zdHJva2UoKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoNSklMjBpbnN0YW50aWF0ZSUyMGNhbWVyYSUyMGhhbmRsaW5nJTIwKHNlZSUyMGh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNicmFuZG9saW5vJTJGY2FtdmFzKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMColMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjBteWNhbXZhcyUyMCUzRCUyMG5ldyUyMGNhbXZhcyhjdHglMkMlMjBwcm9jZXNzZm4pJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGKiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCg2KSUyMGl0JTIwc2VlbXMlMjB0aGF0JTIwZXZlcnl0aGluZyUyMHdlbnQlMjB3ZWxsJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGluaXRpYWxpemVkJTIwJTNEJTIwdHJ1ZSUzQiUwQSUyMCUyMCUyMCUyMCU3RCUwQSUzQyUyRnNjcmlwdCUzRSUwQSUzQ2JvZHklM0UlMEElM0NwJTNFJTBBJTNDZGl2JTIwc3R5bGUlM0QlMjJ0ZXh0LWFsaWduJTNBJTIwY2VudGVyJTNCJTIyJTNFJTNDaW5wdXQlMjB0eXBlJTNEJTIyYnV0dG9uJTIyJTIwdmFsdWUlM0QlMjJTY2FuJTIwbXklMjBzb3VsISUyMiUyMG9uY2xpY2slM0QlMjJidXR0b25fY2FsbGJhY2soKSUyMiUzRSUzQyUyRmRpdiUzRSUwQSUzQyUyRnAlM0UlMEElM0NwJTNFJTBBJTNDZGl2JTIwc3R5bGUlM0QlMjJ0ZXh0LWFsaWduJTNBJTIwY2VudGVyJTNCJTIyJTNFJTBBJTIwJTIwJTIwJTIwJTNDY2FudmFzJTIwd2lkdGglM0Q2NDAlMjBoZWlnaHQlM0Q0ODAlM0UlM0MlMkZjYW52YXMlM0UlMEElM0MlMkZkaXYlM0UlMEElM0MlMkZwJTNFJTBBJTBBJTNDJTJGZGl2JTNFJTBBJTNDJTJGYm9keSUzRSUwQSUzQyUyRmh0bWwlM0UlMEElM0MlMkZib2R5JTNFJTBB"&gt;https://jstrieb.github.io/urlpages/#JTBBJTNDIURPQ1RZUEUlMjBodG1sJTNFJTBBJTNDaGVhZCUzRSUwQSUzQ3N0eWxlJTNFJTBBJTBBJTNDJTJGc3R5bGUlM0UlMEElM0NzY3JpcHQlMjB0eXBlJTNEJTIydGV4dCUyRmphdmFzY3JpcHQlMjIlM0UlMEElMkYqJTIwVGhpcyUyMGxpYnJhcnklMjBpcyUyMHJlbGVhc2VkJTIwdW5kZXIlMjB0aGUlMjBNSVQlMjBsaWNlbnNlJTJDJTIwc2VlJTIwaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGdGVobm9rdiUyRnBpY29qcyUyMColMkYlMEFwaWNvJTIwJTNEJTIwJTdCJTdEJTBBJTBBcGljby51bnBhY2tfY2FzY2FkZSUyMCUzRCUyMGZ1bmN0aW9uKGJ5dGVzKSUwQSU3QiUwQSUwOSUyRiUyRiUwQSUwOWNvbnN0JTIwZHZpZXclMjAlM0QlMjBuZXclMjBEYXRhVmlldyhuZXclMjBBcnJheUJ1ZmZlcig0KSklM0IlMEElMDklMkYqJTBBJTA5JTA5d2UlMjBza2lwJTIwdGhlJTIwZmlyc3QlMjA4JTIwYnl0ZXMlMjBvZiUyMHRoZSUyMGNhc2NhZGUlMjBmaWxlJTBBJTA5JTA5KGNhc2NhZGUlMjB2ZXJzaW9uJTIwbnVtYmVyJTIwYW5kJTIwc29tZSUyMGRhdGElMjB1c2VkJTIwZHVyaW5nJTIwdGhlJTIwbGVhcm5pbmclMjBwcm9jZXNzKSUwQSUwOSolMkYlMEElMDlsZXQlMjBwJTIwJTNEJTIwOCUzQiUwQSUwOSUyRiolMEElMDklMDlyZWFkJTIwdGhlJTIwZGVwdGglMjAoc2l6ZSklMjBvZiUyMGVhY2glMjB0cmVlJTIwZmlyc3QlM0ElMjBhJTIwMzItYml0JTIwc2lnbmVkJTIwaW50ZWdlciUwQSUwOSolMkYlMEElMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDljb25zdCUyMHRkZXB0aCUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUwQSUwOSUyRiolMEElMDklMDluZXh0JTJDJTIwcmVhZCUyMHRoZSUyMG51bWJlciUyMG9mJTIwdHJlZXMlMjBpbiUyMHRoZSUyMGNhc2NhZGUlM0ElMjBhbm90aGVyJTIwMzItYml0JTIwc2lnbmVkJTIwaW50ZWdlciUwQSUwOSolMkYlMEElMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDljb25zdCUyMG50cmVlcyUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUwQSUwOSUyRiolMEElMDklMDlyZWFkJTIwdGhlJTIwYWN0dWFsJTIwdHJlZXMlMjBhbmQlMjBjYXNjYWRlJTIwdGhyZXNob2xkcyUwQSUwOSolMkYlMEElMDljb25zdCUyMHRjb2Rlc19scyUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOWNvbnN0JTIwdHByZWRzX2xzJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTA5Y29uc3QlMjB0aHJlc2hfbHMlMjAlM0QlMjAlNUIlNUQlM0IlMEElMDlmb3IobGV0JTIwdCUzRDAlM0IlMjB0JTNDbnRyZWVzJTNCJTIwJTJCJTJCdCklMEElMDklN0IlMEElMDklMDklMkYlMkYlMjByZWFkJTIwdGhlJTIwYmluYXJ5JTIwdGVzdHMlMjBwbGFjZWQlMjBpbiUyMGludGVybmFsJTIwdHJlZSUyMG5vZGVzJTBBJTA5JTA5QXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkodGNvZGVzX2xzJTJDJTIwJTVCMCUyQyUyMDAlMkMlMjAwJTJDJTIwMCU1RCklM0IlMEElMDklMDlBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0Y29kZXNfbHMlMkMlMjBieXRlcy5zbGljZShwJTJDJTIwcCUyQjQqTWF0aC5wb3coMiUyQyUyMHRkZXB0aCktNCkpJTNCJTBBJTA5JTA5cCUyMCUzRCUyMHAlMjAlMkIlMjA0Kk1hdGgucG93KDIlMkMlMjB0ZGVwdGgpLTQlM0IlMEElMDklMDklMkYlMkYlMjByZWFkJTIwdGhlJTIwcHJlZGljdGlvbiUyMGluJTIwdGhlJTIwbGVhZiUyMG5vZGVzJTIwb2YlMjB0aGUlMjB0cmVlJTBBJTA5JTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ01hdGgucG93KDIlMkMlMjB0ZGVwdGgpJTNCJTIwJTJCJTJCaSklMEElMDklMDklN0IlMEElMDklMDklMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDklMDklMDl0cHJlZHNfbHMucHVzaChkdmlldy5nZXRGbG9hdDMyKDAlMkMlMjB0cnVlKSklM0IlMEElMDklMDklMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQlM0IlMEElMDklMDklN0QlMEElMDklMDklMkYlMkYlMjByZWFkJTIwdGhlJTIwdGhyZXNob2xkJTBBJTA5JTA5ZHZpZXcuc2V0VWludDgoMCUyQyUyMGJ5dGVzJTVCcCUyQjAlNUQpJTJDJTIwZHZpZXcuc2V0VWludDgoMSUyQyUyMGJ5dGVzJTVCcCUyQjElNUQpJTJDJTIwZHZpZXcuc2V0VWludDgoMiUyQyUyMGJ5dGVzJTVCcCUyQjIlNUQpJTJDJTIwZHZpZXcuc2V0VWludDgoMyUyQyUyMGJ5dGVzJTVCcCUyQjMlNUQpJTNCJTBBJTA5JTA5dGhyZXNoX2xzLnB1c2goZHZpZXcuZ2V0RmxvYXQzMigwJTJDJTIwdHJ1ZSkpJTNCJTBBJTA5JTA5cCUyMCUzRCUyMHAlMjAlMkIlMjA0JTNCJTBBJTA5JTdEJTBBJTA5Y29uc3QlMjB0Y29kZXMlMjAlM0QlMjBuZXclMjBJbnQ4QXJyYXkodGNvZGVzX2xzKSUzQiUwQSUwOWNvbnN0JTIwdHByZWRzJTIwJTNEJTIwbmV3JTIwRmxvYXQzMkFycmF5KHRwcmVkc19scyklM0IlMEElMDljb25zdCUyMHRocmVzaCUyMCUzRCUyMG5ldyUyMEZsb2F0MzJBcnJheSh0aHJlc2hfbHMpJTNCJTBBJTA5JTJGKiUwQSUwOSUwOWNvbnN0cnVjdCUyMHRoZSUyMGNsYXNzaWZpY2F0aW9uJTIwZnVuY3Rpb24lMjBmcm9tJTIwdGhlJTIwcmVhZCUyMGRhdGElMEElMDkqJTJGJTBBJTA5ZnVuY3Rpb24lMjBjbGFzc2lmeV9yZWdpb24ociUyQyUyMGMlMkMlMjBzJTJDJTIwcGl4ZWxzJTJDJTIwbGRpbSklMEElMDklN0IlMEElMDklMDklMjByJTIwJTNEJTIwMjU2KnIlM0IlMEElMDklMDklMjBjJTIwJTNEJTIwMjU2KmMlM0IlMEElMDklMDklMjBsZXQlMjByb290JTIwJTNEJTIwMCUzQiUwQSUwOSUwOSUyMGxldCUyMG8lMjAlM0QlMjAwLjAlM0IlMEElMDklMDklMjBjb25zdCUyMHBvdzJ0ZGVwdGglMjAlM0QlMjBNYXRoLnBvdygyJTJDJTIwdGRlcHRoKSUyMCUzRSUzRSUyMDAlM0IlMjAlMkYlMkYlMjAnJTNFJTNFMCclMjB0cmFuc2Zvcm1zJTIwdGhpcyUyMG51bWJlciUyMHRvJTIwaW50JTBBJTBBJTA5JTA5JTIwZm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ250cmVlcyUzQiUyMCUyQiUyQmkpJTBBJTA5JTA5JTIwJTdCJTBBJTA5JTA5JTA5aWR4JTIwJTNEJTIwMSUzQiUwQSUwOSUwOSUwOWZvcihsZXQlMjBqJTNEMCUzQiUyMGolM0N0ZGVwdGglM0IlMjAlMkIlMkJqKSUwQSUwOSUwOSUwOSUwOSUyRiUyRiUyMHdlJTIwdXNlJTIwJyUzRSUzRSUyMDgnJTIwaGVyZSUyMHRvJTIwcGVyZm9ybSUyMGFuJTIwaW50ZWdlciUyMGRpdmlzaW9uJTNBJTIwdGhpcyUyMHNlZW1zJTIwaW1wb3J0YW50JTIwZm9yJTIwcGVyZm9ybWFuY2UlMEElMDklMDklMDklMDlpZHglMjAlM0QlMjAyKmlkeCUyMCUyQiUyMChwaXhlbHMlNUIoKHIlMkJ0Y29kZXMlNUJyb290JTIwJTJCJTIwNCppZHglMjAlMkIlMjAwJTVEKnMpJTIwJTNFJTNFJTIwOCkqbGRpbSUyQigoYyUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDElNUQqcyklMjAlM0UlM0UlMjA4KSU1RCUzQyUzRHBpeGVscyU1QigociUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDIlNUQqcyklMjAlM0UlM0UlMjA4KSpsZGltJTJCKChjJTJCdGNvZGVzJTVCcm9vdCUyMCUyQiUyMDQqaWR4JTIwJTJCJTIwMyU1RCpzKSUyMCUzRSUzRSUyMDgpJTVEKSUzQiUwQSUwQSUwOSUwOSUwOSUyMG8lMjAlM0QlMjBvJTIwJTJCJTIwdHByZWRzJTVCcG93MnRkZXB0aCppJTIwJTJCJTIwaWR4LXBvdzJ0ZGVwdGglNUQlM0IlMEElMEElMDklMDklMDklMjBpZihvJTNDJTNEdGhyZXNoJTVCaSU1RCklMEElMDklMDklMDklMDklMjByZXR1cm4lMjAtMSUzQiUwQSUwQSUwOSUwOSUwOSUyMHJvb3QlMjAlMkIlM0QlMjA0KnBvdzJ0ZGVwdGglM0IlMEElMDklMDklN0QlMEElMDklMDlyZXR1cm4lMjBvJTIwLSUyMHRocmVzaCU1Qm50cmVlcy0xJTVEJTNCJTBBJTA5JTdEJTBBJTA5JTJGKiUwQSUwOSUwOXdlJ3JlJTIwZG9uZSUwQSUwOSolMkYlMEElMDlyZXR1cm4lMjBjbGFzc2lmeV9yZWdpb24lM0IlMEElN0QlMEElMEFwaWNvLnJ1bl9jYXNjYWRlJTIwJTNEJTIwZnVuY3Rpb24oaW1hZ2UlMkMlMjBjbGFzc2lmeV9yZWdpb24lMkMlMjBwYXJhbXMpJTBBJTdCJTBBJTA5Y29uc3QlMjBwaXhlbHMlMjAlM0QlMjBpbWFnZS5waXhlbHMlM0IlMEElMDljb25zdCUyMG5yb3dzJTIwJTNEJTIwaW1hZ2UubnJvd3MlM0IlMEElMDljb25zdCUyMG5jb2xzJTIwJTNEJTIwaW1hZ2UubmNvbHMlM0IlMEElMDljb25zdCUyMGxkaW0lMjAlM0QlMjBpbWFnZS5sZGltJTNCJTBBJTBBJTA5Y29uc3QlMjBzaGlmdGZhY3RvciUyMCUzRCUyMHBhcmFtcy5zaGlmdGZhY3RvciUzQiUwQSUwOWNvbnN0JTIwbWluc2l6ZSUyMCUzRCUyMHBhcmFtcy5taW5zaXplJTNCJTBBJTA5Y29uc3QlMjBtYXhzaXplJTIwJTNEJTIwcGFyYW1zLm1heHNpemUlM0IlMEElMDljb25zdCUyMHNjYWxlZmFjdG9yJTIwJTNEJTIwcGFyYW1zLnNjYWxlZmFjdG9yJTNCJTBBJTBBJTA5bGV0JTIwc2NhbGUlMjAlM0QlMjBtaW5zaXplJTNCJTBBJTA5Y29uc3QlMjBkZXRlY3Rpb25zJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTBBJTA5d2hpbGUoc2NhbGUlM0MlM0RtYXhzaXplKSUwQSUwOSU3QiUwQSUwOSUwOWNvbnN0JTIwc3RlcCUyMCUzRCUyME1hdGgubWF4KHNoaWZ0ZmFjdG9yKnNjYWxlJTJDJTIwMSklMjAlM0UlM0UlMjAwJTNCJTIwJTJGJTJGJTIwJyUzRSUzRTAnJTIwdHJhbnNmb3JtcyUyMHRoaXMlMjBudW1iZXIlMjB0byUyMGludCUwQSUwOSUwOWNvbnN0JTIwb2Zmc2V0JTIwJTNEJTIwKHNjYWxlJTJGMiUyMCUyQiUyMDEpJTIwJTNFJTNFJTIwMCUzQiUwQSUwQSUwOSUwOWZvcihsZXQlMjByJTNEb2Zmc2V0JTNCJTIwciUzQyUzRG5yb3dzLW9mZnNldCUzQiUyMHIlMkIlM0RzdGVwKSUwQSUwOSUwOSUwOWZvcihsZXQlMjBjJTNEb2Zmc2V0JTNCJTIwYyUzQyUzRG5jb2xzLW9mZnNldCUzQiUyMGMlMkIlM0RzdGVwKSUwQSUwOSUwOSUwOSU3QiUwQSUwOSUwOSUwOSUwOWNvbnN0JTIwcSUyMCUzRCUyMGNsYXNzaWZ5X3JlZ2lvbihyJTJDJTIwYyUyQyUyMHNjYWxlJTJDJTIwcGl4ZWxzJTJDJTIwbGRpbSklM0IlMEElMDklMDklMDklMDlpZiUyMChxJTIwJTNFJTIwMC4wKSUwQSUwOSUwOSUwOSUwOSUwOWRldGVjdGlvbnMucHVzaCglNUJyJTJDJTIwYyUyQyUyMHNjYWxlJTJDJTIwcSU1RCklM0IlMEElMDklMDklMDklN0QlMEElMDklMDklMEElMDklMDlzY2FsZSUyMCUzRCUyMHNjYWxlKnNjYWxlZmFjdG9yJTNCJTBBJTA5JTdEJTBBJTBBJTIwJTIwJTIwJTIwcmV0dXJuJTIwZGV0ZWN0aW9ucyUzQiUwQSU3RCUwQSUwQXBpY28uY2x1c3Rlcl9kZXRlY3Rpb25zJTIwJTNEJTIwZnVuY3Rpb24oZGV0cyUyQyUyMGlvdXRocmVzaG9sZCklMEElN0IlMEElMDklMkYqJTBBJTA5JTA5c29ydCUyMGRldGVjdGlvbnMlMjBieSUyMHRoZWlyJTIwc2NvcmUlMEElMDkqJTJGJTBBJTA5ZGV0cyUyMCUzRCUyMGRldHMuc29ydChmdW5jdGlvbihhJTJDJTIwYiklMjAlN0IlMEElMDklMDlyZXR1cm4lMjBiJTVCMyU1RCUyMC0lMjBhJTVCMyU1RCUzQiUwQSUwOSU3RCklM0IlMEElMDklMkYqJTBBJTA5JTA5dGhpcyUyMGhlbHBlciUyMGZ1bmN0aW9uJTIwY2FsY3VsYXRlcyUyMHRoZSUyMGludGVyc2VjdGlvbiUyMG92ZXIlMjB1bmlvbiUyMGZvciUyMHR3byUyMGRldGVjdGlvbnMlMEElMDkqJTJGJTBBJTA5ZnVuY3Rpb24lMjBjYWxjdWxhdGVfaW91KGRldDElMkMlMjBkZXQyKSUwQSUwOSU3QiUwQSUwOSUwOSUyRiUyRiUyMHVucGFjayUyMHRoZSUyMHBvc2l0aW9uJTIwYW5kJTIwc2l6ZSUyMG9mJTIwZWFjaCUyMGRldGVjdGlvbiUwQSUwOSUwOWNvbnN0JTIwcjElM0RkZXQxJTVCMCU1RCUyQyUyMGMxJTNEZGV0MSU1QjElNUQlMkMlMjBzMSUzRGRldDElNUIyJTVEJTNCJTBBJTA5JTA5Y29uc3QlMjByMiUzRGRldDIlNUIwJTVEJTJDJTIwYzIlM0RkZXQyJTVCMSU1RCUyQyUyMHMyJTNEZGV0MiU1QjIlNUQlM0IlMEElMDklMDklMkYlMkYlMjBjYWxjdWxhdGUlMjBkZXRlY3Rpb24lMjBvdmVybGFwJTIwaW4lMjBlYWNoJTIwZGltZW5zaW9uJTBBJTA5JTA5Y29uc3QlMjBvdmVyciUyMCUzRCUyME1hdGgubWF4KDAlMkMlMjBNYXRoLm1pbihyMSUyQnMxJTJGMiUyQyUyMHIyJTJCczIlMkYyKSUyMC0lMjBNYXRoLm1heChyMS1zMSUyRjIlMkMlMjByMi1zMiUyRjIpKSUzQiUwQSUwOSUwOWNvbnN0JTIwb3ZlcmMlMjAlM0QlMjBNYXRoLm1heCgwJTJDJTIwTWF0aC5taW4oYzElMkJzMSUyRjIlMkMlMjBjMiUyQnMyJTJGMiklMjAtJTIwTWF0aC5tYXgoYzEtczElMkYyJTJDJTIwYzItczIlMkYyKSklM0IlMEElMDklMDklMkYlMkYlMjBjYWxjdWxhdGUlMjBhbmQlMjByZXR1cm4lMjBJb1UlMEElMDklMDlyZXR1cm4lMjBvdmVycipvdmVyYyUyRihzMSpzMSUyQnMyKnMyLW92ZXJyKm92ZXJjKSUzQiUwQSUwOSU3RCUwQSUwOSUyRiolMEElMDklMDlkbyUyMGNsdXN0ZXJpbmclMjB0aHJvdWdoJTIwbm9uLW1heGltdW0lMjBzdXBwcmVzc2lvbiUwQSUwOSolMkYlMEElMDljb25zdCUyMGFzc2lnbm1lbnRzJTIwJTNEJTIwbmV3JTIwQXJyYXkoZGV0cy5sZW5ndGgpLmZpbGwoMCklM0IlMEElMDljb25zdCUyMGNsdXN0ZXJzJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ2RldHMubGVuZ3RoJTNCJTIwJTJCJTJCaSklMEElMDklN0IlMEElMDklMDklMkYlMkYlMjBpcyUyMHRoaXMlMjBkZXRlY3Rpb24lMjBhc3NpZ25lZCUyMHRvJTIwYSUyMGNsdXN0ZXIlM0YlMEElMDklMDlpZihhc3NpZ25tZW50cyU1QmklNUQlM0QlM0QwKSUwQSUwOSUwOSU3QiUwQSUwOSUwOSUwOSUyRiUyRiUyMGl0JTIwaXMlMjBub3QlM0ElMEElMDklMDklMDklMkYlMkYlMjBub3clMjB3ZSUyMG1ha2UlMjBhJTIwY2x1c3RlciUyMG91dCUyMG9mJTIwaXQlMjBhbmQlMjBzZWUlMjB3aGV0aGVyJTIwc29tZSUyMG90aGVyJTIwZGV0ZWN0aW9ucyUyMGJlbG9uZyUyMHRvJTIwaXQlMEElMDklMDklMDlsZXQlMjByJTNEMC4wJTJDJTIwYyUzRDAuMCUyQyUyMHMlM0QwLjAlMkMlMjBxJTNEMC4wJTJDJTIwbiUzRDAlM0IlMEElMDklMDklMDlmb3IobGV0JTIwaiUzRGklM0IlMjBqJTNDZGV0cy5sZW5ndGglM0IlMjAlMkIlMkJqKSUwQSUwOSUwOSUwOSUwOWlmKGNhbGN1bGF0ZV9pb3UoZGV0cyU1QmklNUQlMkMlMjBkZXRzJTVCaiU1RCklM0Vpb3V0aHJlc2hvbGQpJTBBJTA5JTA5JTA5JTA5JTdCJTBBJTA5JTA5JTA5JTA5JTA5YXNzaWdubWVudHMlNUJqJTVEJTIwJTNEJTIwMSUzQiUwQSUwOSUwOSUwOSUwOSUwOXIlMjAlM0QlMjByJTIwJTJCJTIwZGV0cyU1QmolNUQlNUIwJTVEJTNCJTBBJTA5JTA5JTA5JTA5JTA5YyUyMCUzRCUyMGMlMjAlMkIlMjBkZXRzJTVCaiU1RCU1QjElNUQlM0IlMEElMDklMDklMDklMDklMDlzJTIwJTNEJTIwcyUyMCUyQiUyMGRldHMlNUJqJTVEJTVCMiU1RCUzQiUwQSUwOSUwOSUwOSUwOSUwOXElMjAlM0QlMjBxJTIwJTJCJTIwZGV0cyU1QmolNUQlNUIzJTVEJTNCJTBBJTA5JTA5JTA5JTA5JTA5biUyMCUzRCUyMG4lMjAlMkIlMjAxJTNCJTBBJTA5JTA5JTA5JTA5JTdEJTBBJTA5JTA5JTA5JTJGJTJGJTIwbWFrZSUyMGElMjBjbHVzdGVyJTIwcmVwcmVzZW50YXRpdmUlMEElMDklMDklMDljbHVzdGVycy5wdXNoKCU1QnIlMkZuJTJDJTIwYyUyRm4lMkMlMjBzJTJGbiUyQyUyMHElNUQpJTNCJTBBJTA5JTA5JTdEJTBBJTA5JTdEJTBBJTBBJTA5cmV0dXJuJTIwY2x1c3RlcnMlM0IlMEElN0QlMEElMEFwaWNvLmluc3RhbnRpYXRlX2RldGVjdGlvbl9tZW1vcnklMjAlM0QlMjBmdW5jdGlvbihzaXplKSUwQSU3QiUwQSUwOSUyRiolMEElMDklMDlpbml0aWFsaXplJTIwYSUyMGNpcmN1bGFyJTIwYnVmZmVyJTIwb2YlMjAlNjBzaXplJTYwJTIwZWxlbWVudHMlMEElMDkqJTJGJTBBJTA5bGV0JTIwbiUyMCUzRCUyMDAlM0IlMEElMDljb25zdCUyMG1lbW9yeSUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOWZvcihsZXQlMjBpJTNEMCUzQiUyMGklM0NzaXplJTNCJTIwJTJCJTJCaSklMEElMDklMDltZW1vcnkucHVzaCglNUIlNUQpJTNCJTBBJTA5JTJGKiUwQSUwOSUwOWJ1aWxkJTIwYSUyMGZ1bmN0aW9uJTIwdGhhdCUzQSUwQSUwOSUwOSgxKSUyMGluc2VydHMlMjB0aGUlMjBjdXJyZW50JTIwZnJhbWUncyUyMGRldGVjdGlvbnMlMjBpbnRvJTIwdGhlJTIwYnVmZmVyJTNCJTBBJTA5JTA5KDIpJTIwbWVyZ2VzJTIwYWxsJTIwZGV0ZWN0aW9ucyUyMGZyb20lMjB0aGUlMjBsYXN0JTIwJTYwc2l6ZSU2MCUyMGZyYW1lcyUyMGFuZCUyMHJldHVybnMlMjB0aGVtJTBBJTA5KiUyRiUwQSUwOWZ1bmN0aW9uJTIwdXBkYXRlX21lbW9yeShkZXRzKSUwQSUwOSU3QiUwQSUwOSUwOW1lbW9yeSU1Qm4lNUQlMjAlM0QlMjBkZXRzJTNCJTBBJTA5JTA5biUyMCUzRCUyMChuJTJCMSklMjVtZW1vcnkubGVuZ3RoJTNCJTBBJTA5JTA5ZGV0cyUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOSUwOWZvcihpJTNEMCUzQiUyMGklM0NtZW1vcnkubGVuZ3RoJTNCJTIwJTJCJTJCaSklMEElMDklMDklMDlkZXRzJTIwJTNEJTIwZGV0cy5jb25jYXQobWVtb3J5JTVCaSU1RCklM0IlMEElMDklMDklMkYlMkYlMEElMDklMDlyZXR1cm4lMjBkZXRzJTNCJTBBJTA5JTdEJTBBJTA5JTJGKiUwQSUwOSUwOXdlJ3JlJTIwZG9uZSUwQSUwOSolMkYlMEElMDlyZXR1cm4lMjB1cGRhdGVfbWVtb3J5JTNCJTBBJTdEJTBBJTBBJTJGKiUyMFRoaXMlMjBsaWJyYXJ5JTIwaXMlMjByZWxlYXNlZCUyMHVuZGVyJTIwdGhlJTIwTUlUJTIwbGljZW5zZSUyQyUyMGNvbnRhY3QlMjAlNDB0ZWhub2t2JTIwZm9yJTIwbW9yZSUyMGRldGFpbHMlMjAqJTJGJTBBbHBsb2MlMjAlM0QlMjAlN0IlN0QlMEElMEFscGxvYy51bnBhY2tfbG9jYWxpemVyJTIwJTNEJTIwZnVuY3Rpb24oYnl0ZXMpJTBBJTdCJTBBJTA5JTJGJTJGJTBBJTA5Y29uc3QlMjBkdmlldyUyMCUzRCUyMG5ldyUyMERhdGFWaWV3KG5ldyUyMEFycmF5QnVmZmVyKDQpKSUzQiUwQSUwOWxldCUyMHAlMjAlM0QlMjAwJTNCJTBBJTA5JTJGKiUwQSUwOSUwOXJlYWQlMjB0aGUlMjBudW1iZXIlMjBvZiUyMHN0YWdlcyUyQyUyMHNjYWxlJTIwbXVsdGlwbGllciUyMChhcHBsaWVkJTIwYWZ0ZXIlMjBlYWNoJTIwc3RhZ2UpJTJDJTBBJTA5JTA5bnVtYmVyJTIwb2YlMjB0cmVlcyUyMHBlciUyMHN0YWdlJTIwYW5kJTIwZGVwdGglMjBvZiUyMGVhY2glMjB0cmVlJTBBJTA5KiUyRiUwQSUwOWR2aWV3LnNldFVpbnQ4KDAlMkMlMjBieXRlcyU1QnAlMkIwJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDElMkMlMjBieXRlcyU1QnAlMkIxJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDIlMkMlMjBieXRlcyU1QnAlMkIyJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDMlMkMlMjBieXRlcyU1QnAlMkIzJTVEKSUzQiUwQSUwOWNvbnN0JTIwbnN0YWdlcyUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUzQiUwQSUwOWR2aWV3LnNldFVpbnQ4KDAlMkMlMjBieXRlcyU1QnAlMkIwJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDElMkMlMjBieXRlcyU1QnAlMkIxJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDIlMkMlMjBieXRlcyU1QnAlMkIyJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDMlMkMlMjBieXRlcyU1QnAlMkIzJTVEKSUzQiUwQSUwOWNvbnN0JTIwc2NhbGVtdWwlMjAlM0QlMjBkdmlldy5nZXRGbG9hdDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUzQiUwQSUwOWR2aWV3LnNldFVpbnQ4KDAlMkMlMjBieXRlcyU1QnAlMkIwJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDElMkMlMjBieXRlcyU1QnAlMkIxJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDIlMkMlMjBieXRlcyU1QnAlMkIyJTVEKSUyQyUyMGR2aWV3LnNldFVpbnQ4KDMlMkMlMjBieXRlcyU1QnAlMkIzJTVEKSUzQiUwQSUwOWNvbnN0JTIwbnRyZWVzcGVyc3RhZ2UlMjAlM0QlMjBkdmlldy5nZXRJbnQzMigwJTJDJTIwdHJ1ZSklM0IlMEElMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQlM0IlMEElMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDljb25zdCUyMHRkZXB0aCUyMCUzRCUyMGR2aWV3LmdldEludDMyKDAlMkMlMjB0cnVlKSUzQiUwQSUwOXAlMjAlM0QlMjBwJTIwJTJCJTIwNCUzQiUwQSUwOSUyRiolMEElMDklMDl1bnBhY2slMjB0aGUlMjB0cmVlcyUwQSUwOSolMkYlMEElMDljb25zdCUyMHRjb2Rlc19scyUyMCUzRCUyMCU1QiU1RCUzQiUwQSUwOWNvbnN0JTIwdHByZWRzX2xzJTIwJTNEJTIwJTVCJTVEJTNCJTBBJTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ25zdGFnZXMlM0IlMjAlMkIlMkJpKSUwQSUwOSU3QiUwQSUwOSUwOSUyRiUyRiUyMHJlYWQlMjB0aGUlMjB0cmVlcyUyMGZvciUyMHRoaXMlMjBzdGFnZSUwQSUwOSUwOWZvcihsZXQlMjBqJTNEMCUzQiUyMGolM0NudHJlZXNwZXJzdGFnZSUzQiUyMCUyQiUyQmopJTBBJTA5JTA5JTdCJTBBJTA5JTA5JTA5JTJGJTJGJTIwYmluYXJ5JTIwdGVzdHMlMjAod2UlMjBjYW4lMjByZWFkJTIwYWxsJTIwb2YlMjB0aGVtJTIwYXQlMjBvbmNlKSUwQSUwOSUwOSUwOUFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRjb2Rlc19scyUyQyUyMGJ5dGVzLnNsaWNlKHAlMkMlMjBwJTJCNCpNYXRoLnBvdygyJTJDJTIwdGRlcHRoKS00KSklM0IlMEElMDklMDklMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQqTWF0aC5wb3coMiUyQyUyMHRkZXB0aCktNCUzQiUwQSUwOSUwOSUwOSUyRiUyRiUyMHJlYWQlMjB0aGUlMjBwcmVkaWN0aW9uJTIwaW4lMjB0aGUlMjBsZWFmJTIwbm9kZXMlMjBvZiUyMHRoZSUyMHRyZWUlMEElMDklMDklMDlmb3IobGV0JTIwayUzRDAlM0IlMjBrJTNDTWF0aC5wb3coMiUyQyUyMHRkZXB0aCklM0IlMjAlMkIlMkJrKSUwQSUwOSUwOSUwOSUwOWZvcihsZXQlMjBsJTNEMCUzQiUyMGwlM0MyJTNCJTIwJTJCJTJCbCklMEElMDklMDklMDklMDklN0IlMEElMDklMDklMDklMDklMDlkdmlldy5zZXRVaW50OCgwJTJDJTIwYnl0ZXMlNUJwJTJCMCU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgxJTJDJTIwYnl0ZXMlNUJwJTJCMSU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgyJTJDJTIwYnl0ZXMlNUJwJTJCMiU1RCklMkMlMjBkdmlldy5zZXRVaW50OCgzJTJDJTIwYnl0ZXMlNUJwJTJCMyU1RCklM0IlMEElMDklMDklMDklMDklMDl0cHJlZHNfbHMucHVzaChkdmlldy5nZXRGbG9hdDMyKDAlMkMlMjB0cnVlKSklM0IlMEElMDklMDklMDklMDklMDlwJTIwJTNEJTIwcCUyMCUyQiUyMDQlM0IlMEElMDklMDklMDklMDklN0QlMEElMDklMDklN0QlMEElMDklN0QlMEElMDljb25zdCUyMHRjb2RlcyUyMCUzRCUyMG5ldyUyMEludDhBcnJheSh0Y29kZXNfbHMpJTNCJTBBJTA5Y29uc3QlMjB0cHJlZHMlMjAlM0QlMjBuZXclMjBGbG9hdDMyQXJyYXkodHByZWRzX2xzKSUzQiUwQSUwOSUyRiolMEElMDklMDljb25zdHJ1Y3QlMjB0aGUlMjBsb2NhdGlvbiUyMGVzdGltYXRvbiUyMGZ1bmN0aW9uJTBBJTA5KiUyRiUwQSUwOWZ1bmN0aW9uJTIwbG9jX2Z1bihyJTJDJTIwYyUyQyUyMHMlMkMlMjBwaXhlbHMlMkMlMjBucm93cyUyQyUyMG5jb2xzJTJDJTIwbGRpbSklMEElMDklN0IlMEElMDklMDlsZXQlMjByb290JTIwJTNEJTIwMCUzQiUwQSUwOSUwOWNvbnN0JTIwcG93MnRkZXB0aCUyMCUzRCUyME1hdGgucG93KDIlMkMlMjB0ZGVwdGgpJTIwJTNFJTNFJTIwMCUzQiUyMCUyRiUyRiUyMCclM0UlM0UwJyUyMHRyYW5zZm9ybXMlMjB0aGlzJTIwbnVtYmVyJTIwdG8lMjBpbnQlMEElMEElMDklMDlmb3IobGV0JTIwaSUzRDAlM0IlMjBpJTNDbnN0YWdlcyUzQiUyMCUyQiUyQmkpJTBBJTA5JTA5JTdCJTBBJTA5JTA5JTA5bGV0JTIwZHIlM0QwLjAlMkMlMjBkYyUzRDAuMCUzQiUwQSUwQSUwOSUwOSUwOWZvcihsZXQlMjBqJTNEMCUzQiUyMGolM0NudHJlZXNwZXJzdGFnZSUzQiUyMCUyQiUyQmopJTBBJTA5JTA5JTA5JTdCJTBBJTA5JTA5JTA5JTA5bGV0JTIwaWR4JTIwJTNEJTIwMCUzQiUwQSUwOSUwOSUwOSUwOWZvcih2YXIlMjBrJTNEMCUzQiUyMGslM0N0ZGVwdGglM0IlMjAlMkIlMkJrKSUwQSUwOSUwOSUwOSUwOSU3QiUwQSUwOSUwOSUwOSUwOSUwOWNvbnN0JTIwcjElMjAlM0QlMjBNYXRoLm1pbihucm93cy0xJTJDJTIwTWF0aC5tYXgoMCUyQyUyMCgyNTYqciUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDAlNUQqcyklM0UlM0U4KSklM0IlMEElMDklMDklMDklMDklMDljb25zdCUyMGMxJTIwJTNEJTIwTWF0aC5taW4obmNvbHMtMSUyQyUyME1hdGgubWF4KDAlMkMlMjAoMjU2KmMlMkJ0Y29kZXMlNUJyb290JTIwJTJCJTIwNCppZHglMjAlMkIlMjAxJTVEKnMpJTNFJTNFOCkpJTNCJTBBJTA5JTA5JTA5JTA5JTA5Y29uc3QlMjByMiUyMCUzRCUyME1hdGgubWluKG5yb3dzLTElMkMlMjBNYXRoLm1heCgwJTJDJTIwKDI1NipyJTJCdGNvZGVzJTVCcm9vdCUyMCUyQiUyMDQqaWR4JTIwJTJCJTIwMiU1RCpzKSUzRSUzRTgpKSUzQiUwQSUwOSUwOSUwOSUwOSUwOWNvbnN0JTIwYzIlMjAlM0QlMjBNYXRoLm1pbihuY29scy0xJTJDJTIwTWF0aC5tYXgoMCUyQyUyMCgyNTYqYyUyQnRjb2RlcyU1QnJvb3QlMjAlMkIlMjA0KmlkeCUyMCUyQiUyMDMlNUQqcyklM0UlM0U4KSklM0IlMEElMEElMDklMDklMDklMDklMDlpZHglMjAlM0QlMjAyKmlkeCUyMCUyQiUyMDElMjAlMkIlMjAocGl4ZWxzJTVCcjEqbGRpbSUyQmMxJTVEJTIwJTNFJTIwcGl4ZWxzJTVCcjIqbGRpbSUyQmMyJTVEKSUwQSUwOSUwOSUwOSUwOSU3RCUwQSUwQSUwOSUwOSUwOSUwOWNvbnN0JTIwbHV0aWR4JTIwJTNEJTIwMioobnRyZWVzcGVyc3RhZ2UqcG93MnRkZXB0aCppJTIwJTJCJTIwcG93MnRkZXB0aCpqJTIwJTJCJTIwaWR4JTIwLSUyMChwb3cydGRlcHRoJTIwLSUyMDEpKSUwQSUwOSUwOSUwOSUwOWRyJTIwJTJCJTNEJTIwdHByZWRzJTVCbHV0aWR4JTIwJTJCJTIwMCU1RCUzQiUwQSUwOSUwOSUwOSUwOWRjJTIwJTJCJTNEJTIwdHByZWRzJTVCbHV0aWR4JTIwJTJCJTIwMSU1RCUzQiUwQSUwQSUwOSUwOSUwOSUwOXJvb3QlMjAlMkIlM0QlMjA0KnBvdzJ0ZGVwdGglMjAtJTIwNCUzQiUwQSUwOSUwOSUwOSU3RCUwQSUwQSUwOSUwOSUwOXIlMjAlM0QlMjByJTIwJTJCJTIwZHIqcyUzQiUwQSUwOSUwOSUwOWMlMjAlM0QlMjBjJTIwJTJCJTIwZGMqcyUzQiUwQSUwQSUwOSUwOSUwOXMlMjAlM0QlMjBzKnNjYWxlbXVsJTNCJTBBJTA5JTA5JTdEJTBBJTBBJTA5JTA5cmV0dXJuJTIwJTVCciUyQyUyMGMlNUQlM0IlMEElMDklN0QlMEElMDklMkYqJTBBJTA5JTA5dGhpcyUyMGZ1bmN0aW9uJTIwYXBwbGllcyUyMHJhbmRvbSUyMHBlcnR1cmJhdGlvbnMlMjB0byUyMHRoZSUyMGRlZmF1bHQlMjByZWN0YW5nbGUlMjAociUyQyUyMGMlMkMlMjBzKSUwQSUwOSolMkYlMEElMDlmdW5jdGlvbiUyMGxvY19mdW5fd2l0aF9wZXJ0dXJicyhyJTJDJTIwYyUyQyUyMHMlMkMlMjBucGVydHVyYnMlMkMlMjBpbWFnZSklMEElMDklN0IlMEElMDklMDljb25zdCUyMHJvd3MlM0QlNUIlNUQlMkMlMjBjb2xzJTNEJTVCJTVEJTNCJTBBJTBBJTA5JTA5Zm9yKGxldCUyMGklM0QwJTNCJTIwaSUzQ25wZXJ0dXJicyUzQiUyMCUyQiUyQmkpJTBBJTA5JTA5JTdCJTBBJTA5JTA5JTA5Y29uc3QlMjBfcyUyMCUzRCUyMHMqKDAuOTI1JTIwJTJCJTIwMC4xNSpNYXRoLnJhbmRvbSgpKSUzQiUwQSUwOSUwOSUwOWxldCUyMF9yJTIwJTNEJTIwciUyMCUyQiUyMHMqMC4xNSooMC41JTIwLSUyME1hdGgucmFuZG9tKCkpJTNCJTBBJTA5JTA5JTA5bGV0JTIwX2MlMjAlM0QlMjBjJTIwJTJCJTIwcyowLjE1KigwLjUlMjAtJTIwTWF0aC5yYW5kb20oKSklM0IlMEElMEElMDklMDklMDklNUJfciUyQyUyMF9jJTVEJTIwJTNEJTIwbG9jX2Z1bihfciUyQyUyMF9jJTJDJTIwX3MlMkMlMjBpbWFnZS5waXhlbHMlMkMlMjBpbWFnZS5ucm93cyUyQyUyMGltYWdlLm5jb2xzJTJDJTIwaW1hZ2UubGRpbSklMEElMEElMDklMDklMDlyb3dzLnB1c2goX3IpJTBBJTA5JTA5JTA5Y29scy5wdXNoKF9jKSUwQSUwOSUwOSU3RCUwQSUwQSUwOSUwOSUyRiUyRiUyMHJldHVybiUyMHRoZSUyMG1lZGlhbiUyMGFsb25nJTIwZWFjaCUyMGF4aXMlMEElMDklMDlyb3dzLnNvcnQoKSUwQSUwOSUwOWNvbHMuc29ydCgpJTBBJTBBJTA5JTA5cmV0dXJuJTIwJTVCcm93cyU1Qk1hdGgucm91bmQobnBlcnR1cmJzJTJGMiklNUQlMkMlMjBjb2xzJTVCTWF0aC5yb3VuZChucGVydHVyYnMlMkYyKSU1RCU1RCUzQiUwQSUwOSU3RCUwQSUwOSUyRiolMEElMDklMDl3ZSdyZSUyMGRvbmUlMEElMDkqJTJGJTBBJTA5cmV0dXJuJTIwbG9jX2Z1bl93aXRoX3BlcnR1cmJzJTNCJTBBJTdEJTBBJTBBJTJGKiUwQSUwOVRoaXMlMjBjb2RlJTIwd2FzJTIwdGFrZW4lMjBmcm9tJTIwaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGY2JyYW5kb2xpbm8lMkZjYW12YXMlMjBhbmQlMjBtb2RpZmllZCUyMHRvJTIwc3VpdCUyMG91ciUyMG5lZWRzJTBBKiUyRiUwQSUyRiolMEFDb3B5cmlnaHQlMjAoYyklMjAyMDEyJTIwQ2xhdWRpbyUyMEJyYW5kb2xpbm8lMEElMEFQZXJtaXNzaW9uJTIwaXMlMjBoZXJlYnklMjBncmFudGVkJTJDJTIwZnJlZSUyMG9mJTIwY2hhcmdlJTJDJTIwdG8lMjBhbnklMjBwZXJzb24lMjBvYnRhaW5pbmclMjBhJTIwY29weSUyMG9mJTIwdGhpcyUyMHNvZnR3YXJlJTIwYW5kJTIwYXNzb2NpYXRlZCUyMGRvY3VtZW50YXRpb24lMjBmaWxlcyUyMCh0aGUlMjAlMjJTb2Z0d2FyZSUyMiklMkMlMjB0byUyMGRlYWwlMjBpbiUyMHRoZSUyMFNvZnR3YXJlJTIwd2l0aG91dCUyMHJlc3RyaWN0aW9uJTJDJTIwaW5jbHVkaW5nJTIwd2l0aG91dCUyMGxpbWl0YXRpb24lMjB0aGUlMjByaWdodHMlMjB0byUyMHVzZSUyQyUyMGNvcHklMkMlMjBtb2RpZnklMkMlMjBtZXJnZSUyQyUyMHB1Ymxpc2glMkMlMjBkaXN0cmlidXRlJTJDJTIwc3VibGljZW5zZSUyQyUyMGFuZCUyRm9yJTIwc2VsbCUyMGNvcGllcyUyMG9mJTIwdGhlJTIwU29mdHdhcmUlMkMlMjBhbmQlMjB0byUyMHBlcm1pdCUyMHBlcnNvbnMlMjB0byUyMHdob20lMjB0aGUlMjBTb2Z0d2FyZSUyMGlzJTIwZnVybmlzaGVkJTIwdG8lMjBkbyUyMHNvJTJDJTIwc3ViamVjdCUyMHRvJTIwdGhlJTIwZm9sbG93aW5nJTIwY29uZGl0aW9ucyUzQSUwQSUwQVRoZSUyMGFib3ZlJTIwY29weXJpZ2h0JTIwbm90aWNlJTIwYW5kJTIwdGhpcyUyMHBlcm1pc3Npb24lMjBub3RpY2UlMjBzaGFsbCUyMGJlJTIwaW5jbHVkZWQlMjBpbiUyMGFsbCUyMGNvcGllcyUyMG9yJTIwc3Vic3RhbnRpYWwlMjBwb3J0aW9ucyUyMG9mJTIwdGhlJTIwU29mdHdhcmUuJTBBJTBBVEhFJTIwU09GVFdBUkUlMjBJUyUyMFBST1ZJREVEJTIwJTIyQVMlMjBJUyUyMiUyQyUyMFdJVEhPVVQlMjBXQVJSQU5UWSUyME9GJTIwQU5ZJTIwS0lORCUyQyUyMEVYUFJFU1MlMjBPUiUyMElNUExJRUQlMkMlMjBJTkNMVURJTkclMjBCVVQlMjBOT1QlMjBMSU1JVEVEJTIwVE8lMjBUSEUlMjBXQVJSQU5USUVTJTIwT0YlMjBNRVJDSEFOVEFCSUxJVFklMkMlMjBGSVRORVNTJTIwRk9SJTIwQSUyMFBBUlRJQ1VMQVIlMjBQVVJQT1NFJTIwQU5EJTIwTk9OSU5GUklOR0VNRU5ULiUyMElOJTIwTk8lMjBFVkVOVCUyMFNIQUxMJTIwVEhFJTIwQVVUSE9SUyUyME9SJTIwQ09QWVJJR0hUJTIwSE9MREVSUyUyMEJFJTIwTElBQkxFJTIwRk9SJTIwQU5ZJTIwQ0xBSU0lMkMlMjBEQU1BR0VTJTIwT1IlMjBPVEhFUiUyMExJQUJJTElUWSUyQyUyMFdIRVRIRVIlMjBJTiUyMEFOJTIwQUNUSU9OJTIwT0YlMjBDT05UUkFDVCUyQyUyMFRPUlQlMjBPUiUyME9USEVSV0lTRSUyQyUyMEFSSVNJTkclMjBGUk9NJTJDJTIwT1VUJTIwT0YlMjBPUiUyMElOJTIwQ09OTkVDVElPTiUyMFdJVEglMjBUSEUlMjBTT0ZUV0FSRSUyME9SJTIwVEhFJTIwVVNFJTIwT1IlMjBPVEhFUiUyMERFQUxJTkdTJTIwSU4lMjBUSEUlMjBTT0ZUV0FSRS4lMEEqJTJGJTBBJTJGJTJGJTIwVGhlJTIwZnVuY3Rpb24lMjB0YWtlcyUyMGElMjBjYW52YXMlMjBjb250ZXh0JTIwYW5kJTIwYSUyMCU2MGRyYXdGdW5jJTYwJTIwZnVuY3Rpb24uJTBBJTJGJTJGJTIwJTYwZHJhd0Z1bmMlNjAlMjByZWNlaXZlcyUyMHR3byUyMHBhcmFtZXRlcnMlMkMlMjB0aGUlMjB2aWRlbyUyMGFuZCUyMHRoZSUyMHRpbWUlMjBzaW5jZSUwQSUyRiUyRiUyMHRoZSUyMGxhc3QlMjB0aW1lJTIwaXQlMjB3YXMlMjBjYWxsZWQuJTBBZnVuY3Rpb24lMjBjYW12YXMoY3R4JTJDJTIwY2FsbGJhY2spJTIwJTdCJTBBJTIwJTIwdmFyJTIwc2VsZiUyMCUzRCUyMHRoaXMlMEElMjAlMjB0aGlzLmN0eCUyMCUzRCUyMGN0eCUwQSUyMCUyMHRoaXMuY2FsbGJhY2slMjAlM0QlMjBjYWxsYmFjayUwQSUwQSUyMCUyMCUyRiUyRiUyMFdlJTIwY2FuJ3QlMjAlNjBuZXclMjBWaWRlbygpJTYwJTIweWV0JTJDJTIwc28lMjB3ZSdsbCUyMHJlc29ydCUyMHRvJTIwdGhlJTIwdmludGFnZSUwQSUyMCUyMCUyRiUyRiUyMCUyMmhpZGRlbiUyMGRpdiUyMiUyMGhhY2slMjBmb3IlMjBkeW5hbWljJTIwbG9hZGluZy4lMEElMjAlMjB2YXIlMjBzdHJlYW1Db250YWluZXIlMjAlM0QlMjBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSUwQSUyMCUyMHRoaXMudmlkZW8lMjAlM0QlMjBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpJTBBJTBBJTIwJTIwJTJGJTJGJTIwSWYlMjB3ZSUyMGRvbid0JTIwZG8lMjB0aGlzJTJDJTIwdGhlJTIwc3RyZWFtJTIwd2lsbCUyMG5vdCUyMGJlJTIwcGxheWVkLiUwQSUyMCUyMCUyRiUyRiUyMEJ5JTIwdGhlJTIwd2F5JTJDJTIwdGhlJTIwcGxheSUyMGFuZCUyMHBhdXNlJTIwY29udHJvbHMlMjB3b3JrJTIwYXMlMjB1c3VhbCUyMCUwQSUyMCUyMCUyRiUyRiUyMGZvciUyMHN0cmVhbWVkJTIwdmlkZW9zLiUwQSUyMCUyMHRoaXMudmlkZW8uc2V0QXR0cmlidXRlKCdhdXRvcGxheSclMkMlMjAnMScpJTBBJTIwJTIwdGhpcy52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJyUyQyUyMCcxJyklMjAlMkYlMkYlMjBpbXBvcnRhbnQlMjBmb3IlMjBpUGhvbmVzJTBBJTBBJTIwJTIwJTJGJTJGJTIwVGhlJTIwdmlkZW8lMjBzaG91bGQlMjBmaWxsJTIwb3V0JTIwYWxsJTIwb2YlMjB0aGUlMjBjYW52YXMlMEElMjAlMjB0aGlzLnZpZGVvLnNldEF0dHJpYnV0ZSgnd2lkdGgnJTJDJTIwMSklMEElMjAlMjB0aGlzLnZpZGVvLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyUyQyUyMDEpJTBBJTBBJTIwJTIwc3RyZWFtQ29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMudmlkZW8pJTBBJTIwJTIwZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzdHJlYW1Db250YWluZXIpJTBBJTBBJTIwJTIwJTJGJTJGJTIwVGhlJTIwY2FsbGJhY2slMjBoYXBwZW5zJTIwd2hlbiUyMHdlJTIwYXJlJTIwc3RhcnRpbmclMjB0byUyMHN0cmVhbSUyMHRoZSUyMHZpZGVvLiUwQSUyMCUyMG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKCU3QnZpZGVvJTNBJTIwdHJ1ZSUyQyUyMGF1ZGlvJTNBJTIwZmFsc2UlN0QpLnRoZW4oZnVuY3Rpb24oc3RyZWFtKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyRiUyRiUyMFlheSUyQyUyMG5vdyUyMG91ciUyMHdlYmNhbSUyMGlucHV0JTIwaXMlMjB0cmVhdGVkJTIwYXMlMjBhJTIwbm9ybWFsJTIwdmlkZW8lMjBhbmQlMEElMjAlMjAlMjAlMjAlMkYlMkYlMjB3ZSUyMGNhbiUyMHN0YXJ0JTIwaGF2aW5nJTIwZnVuJTBBJTIwJTIwJTIwJTIwc2VsZi52aWRlby5zcmNPYmplY3QlMjAlM0QlMjBzdHJlYW0lMEElMjAlMjAlMjAlMjAlMkYlMkYlMjBMZXQncyUyMHN0YXJ0JTIwZHJhd2luZyUyMHRoZSUyMGNhbnZhcyElMEElMjAlMjAlMjAlMjBzZWxmLnVwZGF0ZSgpJTBBJTIwJTIwJTdEJTJDJTIwZnVuY3Rpb24oZXJyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMHRocm93JTIwZXJyJTBBJTIwJTIwJTdEKSUwQSUwQSUyMCUyMCUyRiUyRiUyMEFzJTIwc29vbiUyMGFzJTIwd2UlMjBjYW4lMjBkcmF3JTIwYSUyMG5ldyUyMGZyYW1lJTIwb24lMjB0aGUlMjBjYW52YXMlMkMlMjB3ZSUyMGNhbGwlMjB0aGUlMjAlNjBkcmF3JTYwJTIwZnVuY3Rpb24lMjAlMEElMjAlMjAlMkYlMkYlMjB3ZSUyMHBhc3NlZCUyMGFzJTIwYSUyMHBhcmFtZXRlci4lMEElMjAlMjB0aGlzLnVwZGF0ZSUyMCUzRCUyMGZ1bmN0aW9uKCklMjAlN0IlMEElMDl2YXIlMjBzZWxmJTIwJTNEJTIwdGhpcyUwQSUyMCUyMCUyMCUyMHZhciUyMGxhc3QlMjAlM0QlMjBEYXRlLm5vdygpJTBBJTIwJTIwJTIwJTIwdmFyJTIwbG9vcCUyMCUzRCUyMGZ1bmN0aW9uKCklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBGb3IlMjBzb21lJTIwZWZmZWN0cyUyQyUyMHlvdSUyMG1pZ2h0JTIwd2FudCUyMHRvJTIwa25vdyUyMGhvdyUyMG11Y2glMjB0aW1lJTIwaXMlMjBwYXNzZWQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBzaW5jZSUyMHRoZSUyMGxhc3QlMjBmcmFtZSUzQiUyMHRoYXQncyUyMHdoeSUyMHdlJTIwcGFzcyUyMGFsb25nJTIwYSUyMERlbHRhJTIwdGltZSUyMCU2MGR0JTYwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwdmFyaWFibGUlMjAoZXhwcmVzc2VkJTIwaW4lMjBtaWxsaXNlY29uZHMpJTBBJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwZHQlMjAlM0QlMjBEYXRlLm5vdygpJTIwLSUyMGxhc3QlMEElMjAlMjAlMjAlMjAlMjAlMjBzZWxmLmNhbGxiYWNrKHNlbGYudmlkZW8lMkMlMjBkdCklMEElMjAlMjAlMjAlMjAlMjAlMjBsYXN0JTIwJTNEJTIwRGF0ZS5ub3coKSUwQSUyMCUyMCUyMCUyMCUyMCUyMHJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKSUyMCUwQSUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMHJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKSUyMCUwQSUyMCUyMCU3RCUyMCUwQSU3RCUwQSUwQSUzQyUyRnNjcmlwdCUzRSUwQSUzQyUyRmhlYWQlM0UlMEElM0Nib2R5JTNFJTBBJTNDIURPQ1RZUEUlMjBodG1sJTNFJTBBJTNDaHRtbCUzRSUwQSUzQ2hlYWQlM0UlMEElMjAlMjAlMjAlMjAlM0NtZXRhJTIwY2hhcnNldCUzRCUyMnV0Zi04JTIyJTNFJTBBJTIwJTIwJTIwJTIwJTNDbWV0YSUyMGh0dHAtZXF1aXYlM0QlMjJYLVVBLUNvbXBhdGlibGUlMjIlMjBjb250ZW50JTNEJTIyY2hyb21lJTNEMSUyMiUzRSUwQSUyMCUyMCUyMCUyMCUzQ3RpdGxlJTNFU3RhciUyMHB1cGlsISUzQyUyRnRpdGxlJTNFJTBBJTIwJTIwJTIwJTIwJTNDc2NyaXB0JTIwc3JjJTNEJTIyY2FtdmFzLmpzJTIyJTNFJTNDJTJGc2NyaXB0JTNFJTBBJTIwJTIwJTIwJTIwJTNDc2NyaXB0JTIwc3JjJTNEJTIyLi4lMkZwaWNvLmpzJTIyJTNFJTNDJTJGc2NyaXB0JTNFJTBBJTIwJTIwJTIwJTIwJTNDc2NyaXB0JTIwc3JjJTNEJTIyLi4lMkZscGxvYy5qcyUyMiUzRSUzQyUyRnNjcmlwdCUzRSUwQSUyMCUyMCUyMCUyMCUzQyEtLSUzQ21ldGElMjBuYW1lJTNEJTIydmlld3BvcnQlMjIlMjBjb250ZW50JTNEJTIyd2lkdGglM0RkZXZpY2Utd2lkdGglMkMlMjBpbml0aWFsLXNjYWxlJTNEMSUyQyUyMHVzZXItc2NhbGFibGUlM0RubyUyMiUzRS0tJTNFJTBBJTNDJTJGaGVhZCUzRSUwQSUzQ3NjcmlwdCUzRSUwQSUyMCUyMCUyMCUyMHZhciUyMGluaXRpYWxpemVkJTIwJTNEJTIwZmFsc2UlM0IlMEElMEElMjAlMjAlMjAlMjBmdW5jdGlvbiUyMGJ1dHRvbl9jYWxsYmFjaygpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGKiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCgwKSUyMGNoZWNrJTIwd2hldGhlciUyMHdlJ3JlJTIwYWxyZWFkeSUyMHJ1bm5pbmclMjBmYWNlJTIwZGV0ZWN0aW9uJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKGluaXRpYWxpemVkKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUzQiUyMCUyRiUyRiUyMGlmJTIweWVzJTJDJTIwdGhlbiUyMGRvJTIwbm90JTIwaW5pdGlhbGl6ZSUyMGV2ZXJ5dGhpbmclMjBhZ2FpbiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoMSklMjBpbml0aWFsaXplJTIwdGhlJTIwcGljby5qcyUyMGZhY2UlMjBkZXRlY3RvciUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMColMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjB1cGRhdGVfbWVtb3J5JTIwJTNEJTIwcGljby5pbnN0YW50aWF0ZV9kZXRlY3Rpb25fbWVtb3J5KDUpJTNCJTIwJTJGJTJGJTIwd2UlMjB3aWxsJTIwdXNlJTIwdGhlJTIwZGV0ZWNpb25zJTIwb2YlMjB0aGUlMjBsYXN0JTIwNSUyMGZyYW1lcyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMGZhY2VmaW5kZXJfY2xhc3NpZnlfcmVnaW9uJTIwJTNEJTIwZnVuY3Rpb24lMjAociUyQyUyMGMlMkMlMjBzJTJDJTIwcGl4ZWxzJTJDJTIwbGRpbSklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAtMS4wJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwY2FzY2FkZXVybCUyMCUzRCUyMCdodHRwcyUzQSUyRiUyRnJhdy5naXRodWJ1c2VyY29udGVudC5jb20lMkZuZW5hZG1hcmt1cyUyRnBpY28lMkZjMmU4MWY5ZDIzY2MxMWQxYTYxMmZkMjFlNGY5ZGUwOTIxYTVkMGQ5JTJGcm50JTJGY2FzY2FkZXMlMkZmYWNlZmluZGVyJyUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZldGNoKGNhc2NhZGV1cmwpLnRoZW4oZnVuY3Rpb24lMjAocmVzcG9uc2UpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVzcG9uc2UuYXJyYXlCdWZmZXIoKS50aGVuKGZ1bmN0aW9uJTIwKGJ1ZmZlciklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjBieXRlcyUyMCUzRCUyMG5ldyUyMEludDhBcnJheShidWZmZXIpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZmFjZWZpbmRlcl9jbGFzc2lmeV9yZWdpb24lMjAlM0QlMjBwaWNvLnVucGFja19jYXNjYWRlKGJ5dGVzKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGNvbnNvbGUubG9nKCcqJTIwZmFjZWZpbmRlciUyMGxvYWRlZCcpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYqJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKDIpJTIwaW5pdGlhbGl6ZSUyMHRoZSUyMGxwbG9jLmpzJTIwbGlicmFyeSUyMHdpdGglMjBhJTIwcHVwaWwlMjBsb2NhbGl6ZXIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAqJTJGJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwZG9fcHVwbG9jJTIwJTNEJTIwZnVuY3Rpb24lMjAociUyQyUyMGMlMkMlMjBzJTJDJTIwbnBlcnR1cmJzJTJDJTIwcGl4ZWxzJTJDJTIwbnJvd3MlMkMlMjBuY29scyUyQyUyMGxkaW0pJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwJTVCLTEuMCUyQyUyMC0xLjAlNUQlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkZ2YXIlMjBwdXBsb2N1cmwlMjAlM0QlMjAnLi4lMkZwdXBsb2MuYmluJyUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMHB1cGxvY3VybCUyMCUzRCUyMCdodHRwcyUzQSUyRiUyRmYwMDIuYmFja2JsYXplYjIuY29tJTJGZmlsZSUyRnRlaG5va3Ytd3d3JTJGcG9zdHMlMkZwdXBsb2Mtd2l0aC10cmVlcyUyRmRlbW8lMkZwdXBsb2MuYmluJyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZldGNoKHB1cGxvY3VybCkudGhlbihmdW5jdGlvbiUyMChyZXNwb25zZSklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXNwb25zZS5hcnJheUJ1ZmZlcigpLnRoZW4oZnVuY3Rpb24lMjAoYnVmZmVyKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMGJ5dGVzJTIwJTNEJTIwbmV3JTIwSW50OEFycmF5KGJ1ZmZlciklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkb19wdXBsb2MlMjAlM0QlMjBscGxvYy51bnBhY2tfbG9jYWxpemVyKGJ5dGVzKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGNvbnNvbGUubG9nKCcqJTIwcHVwbG9jJTIwbG9hZGVkJyklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoMyklMjBnZXQlMjB0aGUlMjBkcmF3aW5nJTIwY29udGV4dCUyMG9uJTIwdGhlJTIwY2FudmFzJTIwYW5kJTIwZGVmaW5lJTIwYSUyMGZ1bmN0aW9uJTIwdG8lMjB0cmFuc2Zvcm0lMjBhbiUyMFJHQkElMjBpbWFnZSUyMHRvJTIwZ3JheXNjYWxlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMGN0eCUyMCUzRCUyMGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdjYW52YXMnKSU1QjAlNUQuZ2V0Q29udGV4dCgnMmQnKSUzQiUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZ1bmN0aW9uJTIwcmdiYV90b19ncmF5c2NhbGUocmdiYSUyQyUyMG5yb3dzJTJDJTIwbmNvbHMpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdmFyJTIwZ3JheSUyMCUzRCUyMG5ldyUyMFVpbnQ4QXJyYXkobnJvd3MlMjAqJTIwbmNvbHMpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZm9yJTIwKHZhciUyMHIlMjAlM0QlMjAwJTNCJTIwciUyMCUzQyUyMG5yb3dzJTNCJTIwJTJCJTJCciklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBmb3IlMjAodmFyJTIwYyUyMCUzRCUyMDAlM0IlMjBjJTIwJTNDJTIwbmNvbHMlM0IlMjAlMkIlMkJjKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMGdyYXklMjAlM0QlMjAwLjIqcmVkJTIwJTJCJTIwMC43KmdyZWVuJTIwJTJCJTIwMC4xKmJsdWUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBncmF5JTVCciUyMColMjBuY29scyUyMCUyQiUyMGMlNUQlMjAlM0QlMjAoMiUyMColMjByZ2JhJTVCciUyMColMjA0JTIwKiUyMG5jb2xzJTIwJTJCJTIwNCUyMColMjBjJTIwJTJCJTIwMCU1RCUyMCUyQiUyMDclMjAqJTIwcmdiYSU1QnIlMjAqJTIwNCUyMColMjBuY29scyUyMCUyQiUyMDQlMjAqJTIwYyUyMCUyQiUyMDElNUQlMjAlMkIlMjAxJTIwKiUyMHJnYmElNUJyJTIwKiUyMDQlMjAqJTIwbmNvbHMlMjAlMkIlMjA0JTIwKiUyMGMlMjAlMkIlMjAyJTVEKSUyMCUyRiUyMDEwJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwZ3JheSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoNCklMjB0aGlzJTIwZnVuY3Rpb24lMjBpcyUyMGNhbGxlZCUyMGVhY2glMjB0aW1lJTIwYSUyMHZpZGVvJTIwZnJhbWUlMjBiZWNvbWVzJTIwYXZhaWxhYmxlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMHByb2Nlc3NmbiUyMCUzRCUyMGZ1bmN0aW9uJTIwKHZpZGVvJTJDJTIwZHQpJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwcmVuZGVyJTIwdGhlJTIwdmlkZW8lMjBmcmFtZSUyMHRvJTIwdGhlJTIwY2FudmFzJTIwZWxlbWVudCUyMGFuZCUyMGV4dHJhY3QlMjBSR0JBJTIwcGl4ZWwlMjBkYXRhJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmRyYXdJbWFnZSh2aWRlbyUyQyUyMDAlMkMlMjAwKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHZhciUyMHJnYmElMjAlM0QlMjBjdHguZ2V0SW1hZ2VEYXRhKDAlMkMlMjAwJTJDJTIwNjQwJTJDJTIwNDgwKS5kYXRhJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwcHJlcGFyZSUyMGlucHV0JTIwdG8lMjAlNjBydW5fY2FzY2FkZSU2MCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGltYWdlJTIwJTNEJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIycGl4ZWxzJTIyJTNBJTIwcmdiYV90b19ncmF5c2NhbGUocmdiYSUyQyUyMDQ4MCUyQyUyMDY0MCklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJucm93cyUyMiUzQSUyMDQ4MCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMm5jb2xzJTIyJTNBJTIwNjQwJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIybGRpbSUyMiUzQSUyMDY0MCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHBhcmFtcyUyMCUzRCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMnNoaWZ0ZmFjdG9yJTIyJTNBJTIwMC4xJTJDJTIwJTJGJTJGJTIwbW92ZSUyMHRoZSUyMGRldGVjdGlvbiUyMHdpbmRvdyUyMGJ5JTIwMTAlMjUlMjBvZiUyMGl0cyUyMHNpemUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJtaW5zaXplJTIyJTNBJTIwMTAwJTJDJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwbWluaW11bSUyMHNpemUlMjBvZiUyMGElMjBmYWNlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIybWF4c2l6ZSUyMiUzQSUyMDEwMDAlMkMlMjAlMjAlMjAlMjAlMkYlMkYlMjBtYXhpbXVtJTIwc2l6ZSUyMG9mJTIwYSUyMGZhY2UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJzY2FsZWZhY3RvciUyMiUzQSUyMDEuMSUyMCUyMCUyRiUyRiUyMGZvciUyMG11bHRpc2NhbGUlMjBwcm9jZXNzaW5nJTNBJTIwcmVzaXplJTIwdGhlJTIwZGV0ZWN0aW9uJTIwd2luZG93JTIwYnklMjAxMCUyNSUyMHdoZW4lMjBtb3ZpbmclMjB0byUyMHRoZSUyMGhpZ2hlciUyMHNjYWxlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwcnVuJTIwdGhlJTIwY2FzY2FkZSUyMG92ZXIlMjB0aGUlMjBmcmFtZSUyMGFuZCUyMGNsdXN0ZXIlMjB0aGUlMjBvYnRhaW5lZCUyMGRldGVjdGlvbnMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBkZXRzJTIwaXMlMjBhbiUyMGFycmF5JTIwdGhhdCUyMGNvbnRhaW5zJTIwKHIlMkMlMjBjJTJDJTIwcyUyQyUyMHEpJTIwcXVhZHJ1cGxldHMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjAocmVwcmVzZW50aW5nJTIwcm93JTJDJTIwY29sdW1uJTJDJTIwc2NhbGUlMjBhbmQlMjBkZXRlY3Rpb24lMjBzY29yZSklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkZXRzJTIwJTNEJTIwcGljby5ydW5fY2FzY2FkZShpbWFnZSUyQyUyMGZhY2VmaW5kZXJfY2xhc3NpZnlfcmVnaW9uJTJDJTIwcGFyYW1zKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRldHMlMjAlM0QlMjB1cGRhdGVfbWVtb3J5KGRldHMpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZGV0cyUyMCUzRCUyMHBpY28uY2x1c3Rlcl9kZXRlY3Rpb25zKGRldHMlMkMlMjAwLjIpJTNCJTIwJTJGJTJGJTIwc2V0JTIwSW9VJTIwdGhyZXNob2xkJTIwdG8lMjAwLjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBkcmF3JTIwZGV0ZWN0aW9ucyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZvciUyMChpJTIwJTNEJTIwMCUzQiUyMGklMjAlM0MlMjBkZXRzLmxlbmd0aCUzQiUyMCUyQiUyQmkpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwY2hlY2slMjB0aGUlMjBkZXRlY3Rpb24lMjBzY29yZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMGlmJTIwaXQncyUyMGFib3ZlJTIwdGhlJTIwdGhyZXNob2xkJTJDJTIwZHJhdyUyMGl0JTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwKHRoZSUyMGNvbnN0YW50JTIwNTAuMCUyMGlzJTIwZW1waXJpY2FsJTNBJTIwb3RoZXIlMjBjYXNjYWRlcyUyMG1pZ2h0JTIwcmVxdWlyZSUyMGElMjBkaWZmZXJlbnQlMjBvbmUpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjAoZGV0cyU1QmklNUQlNUIzJTVEJTIwJTNFJTIwNTAuMCklMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjByJTJDJTIwYyUyQyUyMHMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguYmVnaW5QYXRoKCklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguYXJjKGRldHMlNUJpJTVEJTVCMSU1RCUyQyUyMGRldHMlNUJpJTVEJTVCMCU1RCUyQyUyMGRldHMlNUJpJTVEJTVCMiU1RCUyRjIlMkMlMjAwJTJDJTIwMipNYXRoLlBJJTJDJTIwZmFsc2UpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwY3R4LmxpbmVXaWR0aCUyMCUzRCUyMDMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguc3Ryb2tlU3R5bGUlMjAlM0QlMjAnYmx1ZSclM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBjdHguc3Ryb2tlKCklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBmaW5kJTIwdGhlJTIwZXllJTIwcHVwaWxzJTIwZm9yJTIwZWFjaCUyMGRldGVjdGVkJTIwZmFjZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMHN0YXJ0aW5nJTIwcmVnaW9ucyUyMGZvciUyMGxvY2FsaXphdGlvbiUyMGFyZSUyMGluaXRpYWxpemVkJTIwYmFzZWQlMjBvbiUyMHRoZSUyMGZhY2UlMjBib3VuZGluZyUyMGJveCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiUyRiUyMChwYXJhbWV0ZXJzJTIwYXJlJTIwc2V0JTIwZW1waXJpY2FsbHkpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGJTJGJTIwZmlyc3QlMjBleWUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByJTIwJTNEJTIwZGV0cyU1QmklNUQlNUIwJTVEJTIwLSUyMDAuMDc1JTIwKiUyMGRldHMlNUJpJTVEJTVCMiU1RCUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGMlMjAlM0QlMjBkZXRzJTVCaSU1RCU1QjElNUQlMjAtJTIwMC4xNzUlMjAqJTIwZGV0cyU1QmklNUQlNUIyJTVEJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcyUyMCUzRCUyMDAuMzUlMjAqJTIwZGV0cyU1QmklNUQlNUIyJTVEJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVCciUyQyUyMGMlNUQlMjAlM0QlMjBkb19wdXBsb2MociUyQyUyMGMlMkMlMjBzJTJDJTIwNjMlMkMlMjBpbWFnZSklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMChyJTIwJTNFJTNEJTIwMCUyMCUyNiUyNiUyMGMlMjAlM0UlM0QlMjAwKSUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5iZWdpblBhdGgoKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5hcmMoYyUyQyUyMHIlMkMlMjAxJTJDJTIwMCUyQyUyMDIlMjAqJTIwTWF0aC5QSSUyQyUyMGZhbHNlKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5saW5lV2lkdGglMjAlM0QlMjAzJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LnN0cm9rZVN0eWxlJTIwJTNEJTIwJ3JlZCclM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBjdHguc3Ryb2tlKCklM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMkYlMkYlMjBzZWNvbmQlMjBleWUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByJTIwJTNEJTIwZGV0cyU1QmklNUQlNUIwJTVEJTIwLSUyMDAuMDc1JTIwKiUyMGRldHMlNUJpJTVEJTVCMiU1RCUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGMlMjAlM0QlMjBkZXRzJTVCaSU1RCU1QjElNUQlMjAlMkIlMjAwLjE3NSUyMColMjBkZXRzJTVCaSU1RCU1QjIlNUQlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzJTIwJTNEJTIwMC4zNSUyMColMjBkZXRzJTVCaSU1RCU1QjIlNUQlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUJyJTJDJTIwYyU1RCUyMCUzRCUyMGRvX3B1cGxvYyhyJTJDJTIwYyUyQyUyMHMlMkMlMjA2MyUyQyUyMGltYWdlKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwKHIlMjAlM0UlM0QlMjAwJTIwJTI2JTI2JTIwYyUyMCUzRSUzRCUyMDApJTIwJTdCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmJlZ2luUGF0aCgpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmFyYyhjJTJDJTIwciUyQyUyMDElMkMlMjAwJTJDJTIwMiUyMColMjBNYXRoLlBJJTJDJTIwZmFsc2UpJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY3R4LmxpbmVXaWR0aCUyMCUzRCUyMDMlM0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBjdHguc3Ryb2tlU3R5bGUlMjAlM0QlMjAncmVkJyUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGN0eC5zdHJva2UoKSUzQiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyRiolMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAoNSklMjBpbnN0YW50aWF0ZSUyMGNhbWVyYSUyMGhhbmRsaW5nJTIwKHNlZSUyMGh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNicmFuZG9saW5vJTJGY2FtdmFzKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMColMkYlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB2YXIlMjBteWNhbXZhcyUyMCUzRCUyMG5ldyUyMGNhbXZhcyhjdHglMkMlMjBwcm9jZXNzZm4pJTNCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTJGKiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCg2KSUyMGl0JTIwc2VlbXMlMjB0aGF0JTIwZXZlcnl0aGluZyUyMHdlbnQlMjB3ZWxsJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKiUyRiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGluaXRpYWxpemVkJTIwJTNEJTIwdHJ1ZSUzQiUwQSUyMCUyMCUyMCUyMCU3RCUwQSUzQyUyRnNjcmlwdCUzRSUwQSUzQ2JvZHklM0UlMEElM0NwJTNFJTBBJTNDZGl2JTIwc3R5bGUlM0QlMjJ0ZXh0LWFsaWduJTNBJTIwY2VudGVyJTNCJTIyJTNFJTNDaW5wdXQlMjB0eXBlJTNEJTIyYnV0dG9uJTIyJTIwdmFsdWUlM0QlMjJTY2FuJTIwbXklMjBzb3VsISUyMiUyMG9uY2xpY2slM0QlMjJidXR0b25fY2FsbGJhY2soKSUyMiUzRSUzQyUyRmRpdiUzRSUwQSUzQyUyRnAlM0UlMEElM0NwJTNFJTBBJTNDZGl2JTIwc3R5bGUlM0QlMjJ0ZXh0LWFsaWduJTNBJTIwY2VudGVyJTNCJTIyJTNFJTBBJTIwJTIwJTIwJTIwJTNDY2FudmFzJTIwd2lkdGglM0Q2NDAlMjBoZWlnaHQlM0Q0ODAlM0UlM0MlMkZjYW52YXMlM0UlMEElM0MlMkZkaXYlM0UlMEElM0MlMkZwJTNFJTBBJTBBJTNDJTJGZGl2JTNFJTBBJTNDJTJGYm9keSUzRSUwQSUzQyUyRmh0bWwlM0UlMEElM0MlMkZib2R5JTNFJTBB&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fixing Democracy, Developer Style</title>
      <dc:creator>Yitzi Ginzberg</dc:creator>
      <pubDate>Wed, 26 Jun 2019 15:40:13 +0000</pubDate>
      <link>https://dev.to/yitzi/fixing-democracy-developer-style-5b27</link>
      <guid>https://dev.to/yitzi/fixing-democracy-developer-style-5b27</guid>
      <description>&lt;h4&gt;
  
  
  Submitting forms and scraping data for the public good
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AG1qzri4PoIbSsEh8" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AG1qzri4PoIbSsEh8"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@ushakov_kyryll?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;kyryll ushakov&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The US legal system is stacked against the poor.&lt;/p&gt;

&lt;p&gt;The outcome of any court case is mainly dependent on the amount of money the parties involved can spend on their representation. Wealthy criminals who have harmed others with impunity get let off with a slap on the wrist or less. At the same time, the less financially fortunate can end up with outrageous sentences for the pettiest violations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One of the main drivers of this unjust situation is the cost of legal research. Two companies hold a duopoly on the U.S. market for legal information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Law firms seeking access to precedent-setting legal opinions will need to pay Westlaw or Lexis upwards of $100 per month per license! See “&lt;a href="http://emoglen.law.columbia.edu/twiki/bin/view/LawNetSoc/ElliottPaper1" rel="noopener noreferrer"&gt;The Lexis/Westlaw Duopoly and the Proprietization of Legal Research&lt;/a&gt;” — Columbia.&lt;/p&gt;

&lt;p&gt;To fight this travesty &lt;a href="http://anylaw.com" rel="noopener noreferrer"&gt;AnyLaw&lt;/a&gt; (&lt;a href="https://www.forbes.com/sites/maryjuetten/2019/01/22/free-legal-research-for-all-anylaw" rel="noopener noreferrer"&gt;as seen on forbes.com&lt;/a&gt;) has built a robust, fully-featured, and most importantly, FREE legal search engine!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/7y9QP-Sh4fU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Cool, I know!&lt;/p&gt;

&lt;h3&gt;
  
  
  How we do it
&lt;/h3&gt;

&lt;p&gt;Because this was to be a free solution, we obviously could not have the overhead of licensing the published opinions annually.&lt;/p&gt;

&lt;p&gt;Thankfully, US law requires every state and federal court to maintain a website and publish their legal opinions online.&lt;/p&gt;

&lt;p&gt;The obvious solution, therefore, is to scrape and download the data from the individual court sites.&lt;/p&gt;

&lt;p&gt;Unfortunately, there is no standard. Sites can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;static&lt;/li&gt;
&lt;li&gt;rendered server-side&lt;/li&gt;
&lt;li&gt;dynamic JavaScript sites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Courts are allowed to do as they please in terms of building their site.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It pleases them to do some very interesting things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example have a look at the website of &lt;a href="http://www.courts.state.va.us/scndex.htm" rel="noopener noreferrer"&gt;Virginia’s Supreme Court&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ASpsopEWjZp7ZV43-u9QHZQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ASpsopEWjZp7ZV43-u9QHZQ.png"&gt;&lt;/a&gt;Yikes!!&lt;/p&gt;

&lt;p&gt;Yup, that is every Supreme Court decision since 1995 on a single page. 😕&lt;/p&gt;

&lt;p&gt;TLDR; Each court website needs a bot 😧&lt;/p&gt;

&lt;h4&gt;
  
  
  Case study: Texas
&lt;/h4&gt;

&lt;p&gt;Texas is a great example because of the complexity of their site. This is what our bot is confronted with when it navigates to the &lt;a href="http://www.search.txcourts.gov/CaseSearch.aspx?d=1&amp;amp;coa=cossup" rel="noopener noreferrer"&gt;court system URL&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1002%2F1%2AVoqr5WMG2rWWWykEw-M9Fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1002%2F1%2AVoqr5WMG2rWWWykEw-M9Fw.png"&gt;&lt;/a&gt;a non-exceptional form&lt;/p&gt;

&lt;p&gt;The first thing our bot needs to do is to get a list of all Supreme Court opinions. Since this bot needs to interact with the site, we chose to use &lt;a href="http://htmlunit.sourceforge.net/" rel="noopener noreferrer"&gt;HtmlUnit&lt;/a&gt; by &lt;a href="http://www.gargoylesoftware.com/" rel="noopener noreferrer"&gt;Gargoyle Software Inc.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 1. Install the HtmlUnit dependency. We place the following code snippet into our app's pom.xml. If you are not using Maven, visit the website for additional options.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Step 2. Create a method that fills out and submits the form. This is what such a method looks like:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What’s happening here?&lt;br&gt;&lt;br&gt;
Let’s go through this line by line.&lt;/p&gt;
&lt;h4&gt;
  
  
  Getting the page
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;HtmlPage&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pageUrl&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;HtmlPage page&lt;/code&gt; represents the initial page. &lt;code&gt;HtmlPage&lt;/code&gt; comes from the HtmlUnit library. I use an instance of &lt;code&gt;WebClient&lt;/code&gt;, another HtmlUnit class, to get the &lt;code&gt;HtmlPage&lt;/code&gt; by calling &lt;code&gt;getPage()&lt;/code&gt; on it and providing the URL. The &lt;code&gt;WebClient&lt;/code&gt; instance is initialized with a simple &lt;code&gt;WebClient webClient = New WebClient()&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Getting the form
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;HtmlForm&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFormByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"aspnetForm"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;getFormByName()&lt;/code&gt; method provides us with another &lt;code&gt;HtmlUnit&lt;/code&gt; object, this one representing the form. It is easy to identify the name of any elements that we need using the browser's dev tools as seen below.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/40hyOkqwKYw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting and interacting with the input fields
&lt;/h4&gt;

&lt;p&gt;Since we only want court “opinions” we get the checkbox labeled “opinions”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;HtmlCheckBoxInput&lt;/span&gt; &lt;span class="n"&gt;checkBoxInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ctl00$ContentPlaceHolder1$chkListDocTypes$0"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We “check” it programatically with the line:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;checkBoxInput&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setChecked&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We also need to set a “from” date. We get the “from” field with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;HtmlTextInput&lt;/span&gt; &lt;span class="n"&gt;textField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ctl00$ContentPlaceHolder1$dtDocumentFrom$dateInput"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and “type” in a properly formatted string with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;textField&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getFromDateString&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you are curious about how we get the date string, here is what that looks like:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;This bot runs frequently, so it is sufficient to fetch the most recent opinions.&lt;/p&gt;

&lt;p&gt;Lastly, we need the submit button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;HtmlSubmitInput&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ctl00$ContentPlaceHolder1$btnSearchText"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and finally, &lt;code&gt;button.click()&lt;/code&gt; will submit the form and return the page generated as a result of the submission.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Abz7q0kJdctRlI2I_E5Se9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Abz7q0kJdctRlI2I_E5Se9g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our bot is now seeing a neat list of the most recent Supreme Court opinions. The bot can efficiently run through this list downloading and tagging each document.&lt;/p&gt;

&lt;h4&gt;
  
  
  The results:
&lt;/h4&gt;

&lt;p&gt;After a single run the bot has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;downloaded 541 files from Texas courts!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F523%2F1%2AnDIXiR95NKp2T3iNm87VlQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F523%2F1%2AnDIXiR95NKp2T3iNm87VlQ.png"&gt;&lt;/a&gt;My other computer’s a Mac&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inserted the download info into our database. This info includes the source URL as well as the current location on our server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ATNmvRE-nZB5LNFMqYlyWoQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ATNmvRE-nZB5LNFMqYlyWoQ.png"&gt;&lt;/a&gt;Yes, I know this is NJ. Sue me.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inserted metadata about the case with a foreign key to the download entry. This metadata includes the date of the decision, case title, and issuing court.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F942%2F1%2A-skhnf_Wf0kEPnadEBqGlg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F942%2F1%2A-skhnf_Wf0kEPnadEBqGlg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Grand Finale!!🎉🎉
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AQQXEgdM3zLbuzOhKYM1dzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AQQXEgdM3zLbuzOhKYM1dzw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we can make use of this data by sharing it with the world! All this messy, unorganized data is now beautifully organized, searchable, and tagged. &lt;a href="http://anylaw.com" rel="noopener noreferrer"&gt;Have a look&lt;/a&gt; and you’ll discover some other cool stuff that we’ve done with this data.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;I’m Yitzi 👋&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/codegician" rel="noopener noreferrer"&gt;Yitzi Ginzberg (@codegician) | Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>code</category>
      <category>law</category>
      <category>webscraping</category>
    </item>
  </channel>
</rss>
