[
  {
    "path": ".github/CODEOWNERS",
    "content": ".github/* @andrewstech\nsrc-tauri/* @andrewstech\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "custom: https://www.buymeacoffee.com/blueedgetechno\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug Report\ndescription: File a bug report\ntitle: \"[Bug]: \"\nlabels: [\"bug\"]\nassignees:\n  - android69420\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report!\n  - type: textarea\n    id: what-happened\n    attributes:\n      label: What happened?\n      description: Also tell us, what did you expect to happen?\n      placeholder: Tell us what you see!\n      value: \"A bug happened!\"\n    validations:\n      required: true\n  - type: textarea\n    id: Reproduce\n    attributes:\n      label: To reproduce the behavior?\n      description: Steps to reproduce the behavior.\n      placeholder: opened store\n      value: \"reproduce!\"\n    validations:\n      required: true\n  - type: dropdown\n    id: browsers\n    attributes:\n      label: What browser are you seeing the problem on?\n      multiple: false\n      options:\n        - Firefox\n        - Chrome\n        - Safari\n        - Microsoft Edge\n        - Other Browser\n    validations:\n      required: true\n        \n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: npm\n    directory: /\n    schedule:\n      interval: daily\n\n  - package-ecosystem: github-actions\n    directory: /\n    schedule:\n      interval: daily\n"
  },
  {
    "path": ".github/workflows/Build-Deploy.yml",
    "content": "name: Build & Deploy\n\non:\n  push:\n    branches: [master]\n  workflow_dispatch:\n\njobs:\n  Build-Deploy:\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout code\n      uses: actions/checkout@v3\n\n    - name: Set up Node.js\n      uses: actions/setup-node@v3\n      with:\n        node-version: 16\n        cache: npm\n\n    - name: Build\n      run: npm ci && npm run ghbuild\n\n    - name: Deploy to gh-pages\n      uses: peaceiris/actions-gh-pages@v3\n      with:\n        github_token: ${{ secrets.GITHUB_TOKEN }}\n        cname: android.blueedge.me\n        publish_dir: ./build\n"
  },
  {
    "path": ".github/workflows/Issue-text.yml",
    "content": "name: issue-text\n\non:\n  issues:\n    types: [opened]\n\njobs:\n  comment:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: ben-z/actions-comment-on-issue@1.0.2\n      with:\n        message: \"Hey, thank you for creating an issue. We will normally respond within 24 hours.\"\n        GITHUB_TOKEN: ${{ secrets.BOT }}\n        \n    - uses: stefanbuck/github-issue-parser@v2\n      id: issue-parser\n      with:\n        template-path: .github/ISSUE_TEMPLATE/bug_report.yml\n        \n    - run: echo '${{ steps.issue-parser.outputs.jsonString }}'\n    \n    - run: echo ${{ steps.issue-parser.outputs.issueparser_what_browser_are_you_seeing_the_problem_on }}\n    \n    - uses: actions-ecosystem/action-add-labels@v1\n      with:\n        labels: ${{ steps.issue-parser.outputs.issueparser_what_browser_are_you_seeing_the_problem_on }}\n        github_token: ${{ secrets.BOT }}\n        \n"
  },
  {
    "path": ".github/workflows/PR-Preview.yml",
    "content": "name: Generate PR Preview\n\non:\n  pull_request_target:\n    types: [opened, reopened, synchronize]\n\njobs:\n  Build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: peter-evans/create-or-update-comment@v2\n        id: couc\n        with:\n          body: ⌛ Deploy Preview - Build in Progress\n          issue-number: ${{ github.event.pull_request.number }}\n          token: ${{ secrets.BOT }}\n\n      - uses: actions/checkout@v3\n        with:\n          ref: refs/pull/${{ github.event.pull_request.number }}/merge\n\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 16\n\n      - name: create repo\n        if: ${{ github.event.action == 'opened'}}\n        run: gh repo create blueDroidBot/${{ github.event.pull_request.number }} --public\n        env:\n          GITHUB_TOKEN: ${{ secrets.BOT }}\n\n      - name: Build\n        run: npm ci && npm run ghbuild\n\n      - uses: peaceiris/actions-gh-pages@v3\n        with:\n          personal_token: ${{ secrets.BOT }}\n          publish_dir: ./build\n          external_repository: blueDroidBot/${{ github.event.pull_request.number }}\n\n      - name: Sleep to make sure page gets updated\n        run: sleep 1m\n        shell: bash\n\n      - name: comment Preview Ready\n        uses: peter-evans/create-or-update-comment@v2\n        with:\n          body: |\n            ✔️ Deploy Preview for Ready!\n            😎 Browse the preview: https://android-preview.blueedge.me/${{ github.event.pull_request.number }} !\n            🔍 Inspect the deploy log: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\n          comment-id: ${{ steps.couc.outputs.comment-id }}\n          edit-mode: replace\n          token: ${{ secrets.BOT }}\n\n      - if: ${{ failure() }}\n        uses: peter-evans/create-or-update-comment@v2\n        with:\n          body: |\n            ❌ Deploy Preview failed\n            🔍 Inspect the deploy log: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\n          comment-id: ${{ steps.couc.outputs.comment-id }}\n          edit-mode: replace\n          token: ${{ secrets.BOT }}\n"
  },
  {
    "path": ".github/workflows/desktop.yml",
    "content": "name: publish\non:\n  issues:\n    types:\n      - labeled\njobs:\n  publish-tauri:\n    if: github.event.label.name == 'desktop-release'\n    strategy:\n      fail-fast: false\n      matrix:\n        platform: [macos-latest, ubuntu-latest, windows-latest]\n\n    runs-on: ${{ matrix.platform }}\n    env:\n      CI: false\n    steps:\n      - uses: actions/checkout@v3\n      - name: setup node\n        uses: actions/setup-node@v3\n        with:\n          node-version: 12\n          cache: npm\n\n      - name: git http\n        run: |\n          git config --global url.\"https://github.com/\".insteadOf git@github.com:\n          git config --global url.\"https://\".insteadOf git://\n\n      - name: install Rust stable\n        uses: actions-rs/toolchain@v1\n        with:\n          toolchain: stable\n          \n      - uses: Swatinem/rust-cache@v1\n        with:\n          sharedKey: ${{ matrix.platform }}\n      \n      - name: install webkit2gtk (ubuntu only)\n        if: matrix.platform == 'ubuntu-latest'\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y webkit2gtk-4.0\n\n      - name: CI\n        run: |\n          npm ci\n\n      - name: install app dependencies and build it\n        run: npm run build\n      - uses: tauri-apps/tauri-action@v0\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}\n          TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}\n        with:\n          tagName: __VERSION__ # the action automatically replaces \\_\\_VERSION\\_\\_ with the app version\n          releaseName: \"androidInReact v__VERSION__\"\n          releaseBody: ${{ github.event.issue.body }}\n          releaseDraft: false\n          prerelease: false\n"
  },
  {
    "path": ".github/workflows/package-lock.yml",
    "content": "name: \"Re generate the package-lock file\"\non:\n  workflow_dispatch:\n  \njobs:\n  rebuild:\n    name: reBuild\n    runs-on: windows-latest\n    \n    steps:\n    - name: Checkout code\n      uses: actions/checkout@v3\n    \n    - name: Install Node.js\n      uses: actions/setup-node@v1\n      with:\n        node-version: '16.6.1'\n        \n    - name: remove old one\n      run: rm package-lock.json\n      \n    - name: build new one\n      run:  npm install\n      env:\n          CI: false\n      \n    - name: cpr\n      uses: peter-evans/create-pull-request@v4\n      with:\n        token: ${{ secrets.GITHUB_TOKEN }}\n        commit-message: Update package-lock\n        title: Update package-lock\n        body: Update package-lock  \n"
  },
  {
    "path": ".github/workflows/virus.yml",
    "content": "name: released\n\non:\n  release:\n  workflow_dispatch:  \n\njobs:\n  virustotal:\n    runs-on: ubuntu-latest\n    steps:\n      - name: VirusTotal Scan\n        uses: crazy-max/ghaction-virustotal@v2\n        with:\n          vt_api_key: ${{ secrets.VT_API_KEY }}\n          update_release_body: true\n          files: |\n            .msi$\n            .exe$\n            .deb$\n"
  },
  {
    "path": ".github/workflows/winget.yml",
    "content": "name: Publish to WinGet\non:\n  release:\n    types: [released]\njobs:\n  publish:\n    runs-on: windows-latest # action can only be run on windows\n    steps:\n      - uses: vedantmgoyal2009/winget-releaser@latest\n        with:\n          identifier: blueedge.android11react\n          token: ${{ secrets.BOT }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n/.pnp\n.pnp.js\n.env\ntodo*\n\n# testing\n/coverage\n\n# production\n/build\n/target/\nWixTools\n*.py\nrough*\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "LICENSE",
    "content": "Creative Commons Legal Code\n\nCC0 1.0 Universal\n\n    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE\n    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN\n    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS\n    INFORMATION ON AN \"AS-IS\" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES\n    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS\n    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM\n    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED\n    HEREUNDER.\n\nStatement of Purpose\n\nThe laws of most jurisdictions throughout the world automatically confer\nexclusive Copyright and Related Rights (defined below) upon the creator\nand subsequent owner(s) (each and all, an \"owner\") of an original work of\nauthorship and/or a database (each, a \"Work\").\n\nCertain owners wish to permanently relinquish those rights to a Work for\nthe purpose of contributing to a commons of creative, cultural and\nscientific works (\"Commons\") that the public can reliably and without fear\nof later claims of infringement build upon, modify, incorporate in other\nworks, reuse and redistribute as freely as possible in any form whatsoever\nand for any purposes, including without limitation commercial purposes.\nThese owners may contribute to the Commons to promote the ideal of a free\nculture and the further production of creative, cultural and scientific\nworks, or to gain reputation or greater distribution for their Work in\npart through the use and efforts of others.\n\nFor these and/or other purposes and motivations, and without any\nexpectation of additional consideration or compensation, the person\nassociating CC0 with a Work (the \"Affirmer\"), to the extent that he or she\nis an owner of Copyright and Related Rights in the Work, voluntarily\nelects to apply CC0 to the Work and publicly distribute the Work under its\nterms, with knowledge of his or her Copyright and Related Rights in the\nWork and the meaning and intended legal effect of CC0 on those rights.\n\n1. Copyright and Related Rights. A Work made available under CC0 may be\nprotected by copyright and related or neighboring rights (\"Copyright and\nRelated Rights\"). Copyright and Related Rights include, but are not\nlimited to, the following:\n\n  i. the right to reproduce, adapt, distribute, perform, display,\n     communicate, and translate a Work;\n ii. moral rights retained by the original author(s) and/or performer(s);\niii. publicity and privacy rights pertaining to a person's image or\n     likeness depicted in a Work;\n iv. rights protecting against unfair competition in regards to a Work,\n     subject to the limitations in paragraph 4(a), below;\n  v. rights protecting the extraction, dissemination, use and reuse of data\n     in a Work;\n vi. database rights (such as those arising under Directive 96/9/EC of the\n     European Parliament and of the Council of 11 March 1996 on the legal\n     protection of databases, and under any national implementation\n     thereof, including any amended or successor version of such\n     directive); and\nvii. other similar, equivalent or corresponding rights throughout the\n     world based on applicable law or treaty, and any national\n     implementations thereof.\n\n2. Waiver. To the greatest extent permitted by, but not in contravention\nof, applicable law, Affirmer hereby overtly, fully, permanently,\nirrevocably and unconditionally waives, abandons, and surrenders all of\nAffirmer's Copyright and Related Rights and associated claims and causes\nof action, whether now known or unknown (including existing as well as\nfuture claims and causes of action), in the Work (i) in all territories\nworldwide, (ii) for the maximum duration provided by applicable law or\ntreaty (including future time extensions), (iii) in any current or future\nmedium and for any number of copies, and (iv) for any purpose whatsoever,\nincluding without limitation commercial, advertising or promotional\npurposes (the \"Waiver\"). Affirmer makes the Waiver for the benefit of each\nmember of the public at large and to the detriment of Affirmer's heirs and\nsuccessors, fully intending that such Waiver shall not be subject to\nrevocation, rescission, cancellation, termination, or any other legal or\nequitable action to disrupt the quiet enjoyment of the Work by the public\nas contemplated by Affirmer's express Statement of Purpose.\n\n3. Public License Fallback. Should any part of the Waiver for any reason\nbe judged legally invalid or ineffective under applicable law, then the\nWaiver shall be preserved to the maximum extent permitted taking into\naccount Affirmer's express Statement of Purpose. In addition, to the\nextent the Waiver is so judged Affirmer hereby grants to each affected\nperson a royalty-free, non transferable, non sublicensable, non exclusive,\nirrevocable and unconditional license to exercise Affirmer's Copyright and\nRelated Rights in the Work (i) in all territories worldwide, (ii) for the\nmaximum duration provided by applicable law or treaty (including future\ntime extensions), (iii) in any current or future medium and for any number\nof copies, and (iv) for any purpose whatsoever, including without\nlimitation commercial, advertising or promotional purposes (the\n\"License\"). The License shall be deemed effective as of the date CC0 was\napplied by Affirmer to the Work. Should any part of the License for any\nreason be judged legally invalid or ineffective under applicable law, such\npartial invalidity or ineffectiveness shall not invalidate the remainder\nof the License, and in such case Affirmer hereby affirms that he or she\nwill not (i) exercise any of his or her remaining Copyright and Related\nRights in the Work or (ii) assert any associated claims and causes of\naction with respect to the Work, in either case contrary to Affirmer's\nexpress Statement of Purpose.\n\n4. Limitations and Disclaimers.\n\n a. No trademark or patent rights held by Affirmer are waived, abandoned,\n    surrendered, licensed or otherwise affected by this document.\n b. Affirmer offers the Work as-is and makes no representations or\n    warranties of any kind concerning the Work, express, implied,\n    statutory or otherwise, including without limitation warranties of\n    title, merchantability, fitness for a particular purpose, non\n    infringement, or the absence of latent or other defects, accuracy, or\n    the present or absence of errors, whether or not discoverable, all to\n    the greatest extent permissible under applicable law.\n c. Affirmer disclaims responsibility for clearing rights of other persons\n    that may apply to the Work or any use thereof, including without\n    limitation any person's Copyright and Related Rights in the Work.\n    Further, Affirmer disclaims responsibility for obtaining any necessary\n    consents, permissions or other rights required for any use of the\n    Work.\n d. Affirmer understands and acknowledges that Creative Commons is not a\n    party to this document and has no duty or obligation with respect to\n    this CC0 or use of the Work.\n"
  },
  {
    "path": "README.md",
    "content": "# Android on Web\n\n[![Follow me](https://img.shields.io/github/followers/blueedgetechno?label=follow%20me&style=social)](https://github.com/blueedgetechno)\n[![Follow Twitter](https://img.shields.io/twitter/follow/blueedgetechno?label=Follow%20me&style=social)](https://twitter.com/blueedgetechno)\n[![Join](https://img.shields.io/discord/868499076432408627.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/NcjaNdwtnR)\n[![coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/blueedgetechno)\n\nAn open-source project that aims to provide an indistinguishably accurate experience of Android on web. The project leverages different JavaScript Web APIs to imitates the Android functionalities and CSS animations to bring life into it.\n\n------------\n#### Visit the Live Application🌈: &nbsp; [android.blueedge.me](https://android.blueedge.me)\n\n## Gallery\n![img1](public/gall1.png)\n\n![img1](public/gall2.png)\n\n#### Visit the Live Application🌈: &nbsp; [android.blueedge.me](https://android.blueedge.me)\n\n# Stack\n\n- Framework - React (^17.0.2) + Redux\n- Component/UI Library - Material UI\n- Styling Solution - SCSS and CSS Modules (+ tailwind).\n- Icons - fontAwesome/mui icons/custom svg icons\n\n# Features\n- [x] Home page, App icons\n- [x] Bottom Navigation bar\n- [x] Widgets like google search\n- [x] Calendar, Date, Clock Widgets\n- [x] Quick menu from slide up\n- [x] Recent menu and apps\n- [x] WhatsApp Application\n- [x] YouTube Application\n- [x] Google Search App\n\n# Dev Features\n- [x] Flexible and Scalable\n- [x] Easy to add custom Applications\n- [x] Easy to bind with existing system\n- [x] Built-In Navigation system per app\n- [x] Modular Applications and their styling\n- [x] Proper state management with Redux\n\n## FAQ\n\n1. Is this real android OS?\n    - No, This is not a real operating system. It is just imitation of it with different technology.\n\n\n2. How long did it take?\n    - 6 weeks (without gaps)\n\n\n3. Have you ran into problems during development?\n    - Duhh. More than dozen big ones and hundreds of small problems ([more info](timeline.md)).\n\n\n4. Can I contribute?\n    - Yes, you can! Open an issue, create a pull request, head over to [discussions](https://github.com/blueedgetechno/androidInReact/discussions) or join the [discord](https://discord.gg/NcjaNdwtnR).\n\n\n5. Where did you get the inspiration from, if you have?\n    - I got the inspired to make the project on the suggestion of [Derry Shribman](https://github.com/xderry).\n\n\n6. Why do JavaScript developers wear glasses?\n    - Because they cannot C# (see sharp). &nbsp;&nbsp;&nbsp; ![answer](public/hehe.jpg)\n\n\n## Online Deployment\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)\n\n[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template?template=https%3A%2F%2Fgithub.com%2Fblueedgetechno%2FandroidInReact&envs=PORT&PORTDesc=Port+of+the+application&PORTDefault=3000)\n\n[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/blueedgetechno/androidInReact)\n\n\n## Acknowledgements\n\n- [Derry Shribman](https://github.com/xderry)\n- [React-hammerjs](https://github.com/JedWatson/react-hammerjs)\n- [React-slick](https://github.com/akiran/react-slick)\n\n\n## Contributors\n[![contributors](https://contrib.rocks/image?repo=blueedgetechno/androidInReact)](https://github.com/blueedgetechno/androidInReact/graphs/contributors)\n\n\n## License\n\n⚖️ CC0-1.0 License\n"
  },
  {
    "path": "jsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \"src\"\n  },\n  \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"Android11React\",\n  \"description\": \"Android made in React\",\n  \"repository\": \"https://github.com/blueedgetechno/androidInReact\",\n  \"version\": \"0.0.1\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@emotion/react\": \"^11.9.0\",\n    \"@emotion/styled\": \"^11.8.1\",\n    \"@fortawesome/fontawesome-svg-core\": \"^6.1.1\",\n    \"@fortawesome/free-regular-svg-icons\": \"^6.1.1\",\n    \"@fortawesome/free-solid-svg-icons\": \"^6.1.1\",\n    \"@fortawesome/react-fontawesome\": \"^0.1.18\",\n    \"@mui/icons-material\": \"^5.6.2\",\n    \"@mui/lab\": \"^5.0.0-alpha.83\",\n    \"@mui/material\": \"^5.8.1\",\n    \"@reduxjs/toolkit\": \"^1.8.2\",\n    \"@sentry/react\": \"^6.19.7\",\n    \"@sentry/tracing\": \"^6.19.7\",\n    \"@tauri-apps/api\": \"^1.0.0-rc.6\",\n    \"@win11react/react-hammerjs\": \"1.0.2\",\n    \"axios\": \"^0.27.2\",\n    \"color-parse\": \"^1.4.2\",\n    \"color-rgba\": \"^2.4.0\",\n    \"react\": \"^18.1.0\",\n    \"react-calendar\": \"^3.7.0\",\n    \"react-dom\": \"^18.1.0\",\n    \"react-player\": \"^2.10.1\",\n    \"react-redux\": \"^8.0.2\",\n    \"react-scripts\": \"^5.0.1\",\n    \"react-slick\": \"^0.29.0\",\n    \"redux\": \"^4.2.0\",\n    \"redux-thunk\": \"^2.4.1\",\n    \"slick-carousel\": \"^1.8.1\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"ghbuild\": \"CI=false react-scripts build\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\",\n    \"tauri\": \"tauri\"\n  },\n  \"eslintConfig\": {\n    \"extends\": [\n      \"react-app\",\n      \"react-app/jest\"\n    ]\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@tauri-apps/cli\": \"^1.0.0-rc.12\",\n    \"node-sass\": \"^7.0.1\",\n    \"tailwindcss\": \"^3.0.24\"\n  }\n}\n"
  },
  {
    "path": "public/_redirects",
    "content": "/*  /index.html  200\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"utf-8\" />\n  <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.ico\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" />\n  <meta name=\"theme-color\" content=\"#000000\" />\n  <meta name=\"description\" content=\"Android on web made with React\" />\n\n  <meta name=\"og:title\" property=\"og:title\" content=\"Android in React\" />\n  <meta name=\"og:description\" property=\"og:description\" content=\"Android on web made with React\" />\n  <meta name=\"og:color\" content=\"#303030\" />\n\n  <title>Android in React</title>\n  <link rel=\"apple-touch-icon\" href=\"%PUBLIC_URL%/apple-touch-icon.png\" />\n  <link rel=\"manifest\" href=\"%PUBLIC_URL%/manifest.json\" />\n\n</head>\n\n<body>\n  <noscript>You need to enable JavaScript to run this app.</noscript>\n  <div id=\"root\"></div>\n</body>\n\n</html>\n"
  },
  {
    "path": "public/manifest.json",
    "content": "{\n  \"short_name\": \"Android In React\",\n  \"name\": \"Android on web\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    },\n    {\n      \"src\": \"logo192.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"192x192\"\n    },\n    {\n      \"src\": \"logo512.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"512x512\"\n    }\n  ],\n  \"author\": {\n\t\t\"name\": \"Blue Edge\",\n\t\t\"website\": \"https://blueedge.me\",\n\t\t\"github\": \"https://github.com/blueedgetechno\",\n\t\t\"source-repo\": \"https://github.com/blueedgetechno/androidInReact\"\n\t},\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#fefefe\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\n"
  },
  {
    "path": "public/site.webmanifest",
    "content": "{\n  \"name\": \"\",\n  \"short_name\": \"\",\n  \"icons\": [{\n    \"src\": \"/android-chrome-192x192.png\",\n    \"sizes\": \"192x192\",\n    \"type\": \"image/png\"\n  }, {\n    \"src\": \"/android-chrome-512x512.png\",\n    \"sizes\": \"512x512\",\n    \"type\": \"image/png\"\n  }],\n  \"theme_color\": \"#ffffff\",\n  \"background_color\": \"#ffffff\",\n  \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "src/App.css",
    "content": ".App {\n  --stbar-h: 2.4em;\n}\n\n*[data-ninja=\"true\"] {\n  pointer-events: none;\n}\n\n.uicon {\n  position: relative;\n  display: grid;\n  place-items: center;\n  overflow: hidden;\n}\n\n.text-xss {\n  font-size: 0.64em;\n}\n\n.smooth-trans {\n  transition: all 200ms ease-in-out;\n}\n\n.invert-true,\nimg[data-invert=\"true\"],\nsvg[data-invert=\"true\"],\ni[data-invert=\"true\"] {\n  filter: invert(1);\n}\n\n.rounded-true,\nimg[data-rounded=\"true\"],\nsvg[data-rounded=\"true\"],\ni[data-rounded=\"true\"] {\n  border-radius: 1000px;\n}\n\n.flip-true,\nimg[data-flip=\"true\"],\nsvg[data-flip=\"true\"],\ni[data-flip=\"true\"] {\n  transform: scale(-1, 1);\n}\n\n.uicon img {\n  transform-origin: center;\n  transition: 400ms ease-in-out;\n}\n\n.imageCont, .vidCont{\n  position: relative;\n  display: grid;\n  place-items: center;\n  width: auto;\n  height: auto;\n}\n\n.imageCont &[data-back=\"true\"] {\n  background-position: center;\n  background-size: cover;\n}\n\n.imageCont img[data-free=\"false\"] {\n  max-width: 100%;\n  max-height: 100%;\n}\n\n.imageCont.rounded {\n  overflow: hidden;\n}\n\n.noscroll::-webkit-scrollbar {\n  display: none;\n}\n\n.thinScroll::-webkit-scrollbar {\n  width: 2px;\n  height: 2px;\n  background-color: transparent;\n}\n\n.medScroll::-webkit-scrollbar {\n  width: 4px;\n  height: 4px;\n  background-color: transparent;\n}\n\n.thinScroll:hover::-webkit-scrollbar-thumb,\n.medScroll:hover::-webkit-scrollbar-thumb {\n  background: rgba(32, 24, 148, 0.4);\n}\n\n.lightScroll:hover::-webkit-scrollbar-thumb {\n  background: rgba(162, 159, 209, 0.4);\n}\n\n.thinScroll::-webkit-scrollbar-thumb {\n  width: 2px;\n  height: 2px;\n  border-radius: 10px;\n  background-color: transparent;\n}\n\n.medScroll::-webkit-scrollbar-thumb {\n  width: 4px;\n  height: 4px;\n  border-radius: 10px;\n  background-color: transparent;\n}\n\n.upbug::after {\n  content: \"\";\n  position: absolute;\n  left: 0;\n  top: -2px;\n  width: 100%;\n  height: 4px;\n  background: #128c7e;\n}\n\n.downbug::after {\n  content: \"\";\n  position: absolute;\n  z-index: 1;\n  left: 0;\n  bottom: -2px;\n  width: 100%;\n  height: 4px;\n  background: #128c7e;\n}\n\n@media only screen and (min-width: 520px) {\n  *{\n    /* cursor: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewport='0 0 24 24' width='24' height='24'><circle cx='12' cy='12' r='12' style='fill: rgba(64, 64, 64, 0.2);'></circle><circle cx='12' cy='12' r='10' style='fill: rgba(0, 0, 0, 0.25);'></circle></svg>\"), auto; */\n  }\n}\n"
  },
  {
    "path": "src/App.js",
    "content": "import React, {useState, useEffect} from 'react';\n\nimport {Background, OverLay} from 'components/background';\nimport Home from 'containers/home';\nimport {loadSettings} from 'store/actions/index';\n\nimport 'slick-carousel/slick/slick.css';\nimport 'slick-carousel/slick/slick-theme.css';\nimport './App.css';\n\nfunction App() {\n\n  useEffect(() => {\n    if (!window.onstart) {\n      // console.log(\"Loading settings...\");\n      window.onstart = loadSettings();\n    }\n  });\n\n  return (\n    <div className=\"App\">\n      <div className=\"appwrap\">\n        <Background/>\n        <Home/>\n        <OverLay/>\n      </div>\n    </div>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "src/components/background/back.scss",
    "content": ".background {\n  min-width: 100vw;\n  min-height: 100%;\n  background-color: #fefefe;\n  background-repeat: no-repeat;\n  background-size: cover;\n  background-position: center;\n  transition: all 0.2s ease;\n}\n\n.app-overlay, .brightness-overlay{\n  position: absolute;\n  pointer-events: none;\n  inset: 0;\n}\n\n.brightness-overlay{\n  background: #000;\n}\n"
  },
  {
    "path": "src/components/background/index.js",
    "content": "import React, { useState, useEffect } from 'react';\nimport { useSelector } from 'react-redux';\nimport \"./back.scss\";\n\nexport const Background = () => {\n  const wall = useSelector((state) => state.wallpaper);\n\n  return (\n    <div className=\"background\" style={{\n        backgroundImage: `url(img/wallpaper/${wall.src})`,\n      }}></div>\n  );\n}\n\nexport const OverLay = () => {\n  const bright = useSelector((state) => state.quickpanel.lazy_bright)\n\n  return (\n    <div className=\"app-overlay\">\n      <div className=\"brightness-overlay\" style={{opacity: `${90 - bright*0.9}%`}}></div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "src/components/bottomnav/bottom.scss",
    "content": ".bottom-nav{\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  transition: background-color 200ms ease-in-out;\n}\n\n.bt-nav-container{\n  display: flex;\n  justify-content: space-around;\n  padding: 0.1em 1em;\n  width: 100%;\n  max-width: 50em;\n\n  .uicon{\n    padding: 0.5em;\n    color: var(--med-txt);\n    // filter: drop-shadow(1px 1px 4px rgba(254, 254, 254, 0.6));\n  }\n\n  &[data-invert=\"true\"]{\n    .uicon{\n      color: var(--gray-txt);\n    }\n  }\n\n  .bar-icon{\n    transform: rotateZ(90deg);\n  }\n}\n"
  },
  {
    "path": "src/components/bottomnav/index.js",
    "content": "import React, { useState, useEffect, useRef} from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport {Icon} from 'components/utils';\nimport parse from 'color-parse';\nimport rgba from 'color-rgba';\n\nimport './bottom.scss';\n\nconst BottomNav = (props) => {\n  const [invert, setInvert] = useState(props.invert);\n  const navBar = useRef();\n  const dispatch = useDispatch();\n\n  const istransparent = (bgcolor)=>{\n    var colors = parse(bgcolor)\n    return colors.alpha < 0.1;\n  }\n\n  const refreshInvert = ()=>{\n    var bgcolor = getComputedStyle(navBar.current).getPropertyValue('background-color');\n    if(!istransparent(bgcolor)){\n      var arr = rgba(bgcolor),\n          avg = (arr[0]+arr[1]+arr[2])/3\n\n      if(avg<128) setInvert(true)\n      else setInvert(false)\n    }else setInvert(false)\n  }\n\n  useEffect(()=>{\n    if(navBar.current && props.invert==null){\n      setTimeout(refreshInvert,100)\n    }else if (props.invert!=null) {\n      setInvert(props.invert)\n    }\n  }, [props.bg, props.invert])\n\n  return (\n    <div className=\"bottom-nav\" style={{\n      backgroundColor: props.bg\n    }} ref={navBar}>\n      <div className=\"bt-nav-container\" data-invert={invert}>\n        <Icon className=\"bar-icon press-in\" fafa=\"faBars\" w={16} action=\"home/setRecent\"/>\n        <Icon className=\"press-in\" mui=\"CropSquare\" w={20} action=\"home/setHome\"/>\n        <Icon className=\"press-in\" mui=\"ArrowBackIos\" w={20} action=\"home/goBack\"/>\n      </div>\n    </div>\n  );\n};\n\nexport default BottomNav;\n"
  },
  {
    "path": "src/components/icons.js",
    "content": "export const NetworkIcon = (props) => {\n  // network icon that is responsive to a status props indicating network strength\n  const status = props.status || 4;\n  return (\n    <div className=\"uicon\">\n      <svg\n        viewBox=\"0 0 110 100\"\n        width={props.w}\n        height={props.h || props.w}\n        fill={props.fill}\n      >\n        <rect x={0} y={75} width={20} height={25} rx={5} ry={5}></rect>\n        <rect\n          x={30}\n          y={50}\n          width={20}\n          height={50}\n          rx={5}\n          ry={5}\n          fill={status > 1 ? props.fill : props.filldim}\n        ></rect>\n        <rect\n          x={60}\n          y={25}\n          width={20}\n          height={75}\n          rx={5}\n          ry={5}\n          fill={status > 2 ? props.fill : props.filldim}\n        ></rect>\n        <rect\n          x={90}\n          y={0}\n          width={20}\n          height={100}\n          rx={5}\n          ry={5}\n          fill={status > 3 ? props.fill : props.filldim}\n        ></rect>\n      </svg>\n    </div>\n  );\n};\n\n// Battery Icon by Google Inc. - Iconscout\nexport const BatteryIcon = (props) => {\n  var h = ((props.battery.level || 100)*33);\n\n  return (\n    <div className=\"uicon\">\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 48\"\n        width={props.w}\n        height={props.h || props.w}>\n        <g\n          style={{\n            transform: \"translateX(-12px)\",\n          }}\n          fill={null}>\n          <path d=\"M34 10.67c0-1.48-1.19-2.67-2.67-2.67h-3.33v-4h-8v4h-3.33c-1.48 0-2.67 1.19-2.67 2.67v7.33h20v-7.33z\" />\n          <path d=\"M14 18v23.33c0 1.47 1.19 2.67 2.67 2.67h14.67c1.47 0 2.67-1.19 2.67-2.67v-23.33h-20.01z\" />\n          <rect\n            x={15}\n            y={42.5 - h}\n            width={18}\n            height={h}\n            fill={props.fill}\n            rx={2}></rect>\n          <g style={{ transform: \"translate(19px,16px) scale(0.036)\" }}>\n            <path\n              fill={props.battery.charging ? props.cfill : \"none\"}\n              d=\"M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z\"></path>\n          </g>\n        </g>\n      </svg>\n    </div>\n  );\n};\n\nexport const pinned = (props) => {\n  return (\n    <svg viewBox=\"0 0 16 16\" height={16} width={16} {...props} className={\n      props.flip? \"flip-true\": \"\" +\n      (props.invert? \" invert-true\": \"\") +\n      (props.rounded? \" rounded-true\": \"\")\n    } style={{\n      width: props.w,\n      height: props.h || props.w,\n      color: props.color,\n      margin: props.margin\n    }}>\n      <path\n        d=\"M12.074 4.21 8.7 8.232l.116 4.233a.4.4 0 0 1-.657.318L.43 6.297a.4.4 0 0 1 .199-.702l4.196-.622L8.196.957a.63.63 0 0 1 .887-.078l2.914 2.445a.63.63 0 0 1 .077.887ZM1.294 14.229a.713.713 0 0 1-1.09-.915l2.674-3.64 1.536 1.288-3.12 3.267Z\">\n      </path>\n    </svg>\n  );\n};\n\nexport const seentick = (props) => {\n  return (\n    <svg viewBox=\"0 0 16 15\" width=\"16\" height=\"15\" {...props} className={\n      props.flip? \"flip-true\": \"\" +\n      (props.invert? \" invert-true\": \"\") +\n      (props.rounded? \" rounded-true\": \"\")\n    } style={{\n      width: props.w,\n      height: props.h || props.w,\n      color: props.color,\n      margin: props.margin\n    }}>\n      <path d=\"m15.01 3.316-.478-.372a.365.365 0 0 0-.51.063L8.666 9.879a.32.32 0 0 1-.484.033l-.358-.325a.319.319 0 0 0-.484.032l-.378.483a.418.418 0 0 0 .036.541l1.32 1.266c.143.14.361.125.484-.033l6.272-8.048a.366.366 0 0 0-.064-.512zm-4.1 0-.478-.372a.365.365 0 0 0-.51.063L4.566 9.879a.32.32 0 0 1-.484.033L1.891 7.769a.366.366 0 0 0-.515.006l-.423.433a.364.364 0 0 0 .006.514l3.258 3.185c.143.14.361.125.484-.033l6.272-8.048a.365.365 0 0 0-.063-.51z\">\n      </path>\n    </svg>\n  );\n};\n"
  },
  {
    "path": "src/components/main.scss",
    "content": "body {\n  --dark-txt: #000;\n  --med-dark: #111;\n  --txt-col: #222;\n  --med-txt: #3c3c3c;\n  --comp-txt: #ddd;\n  --light-txt: #aaa;\n  --comp-clr: #e6e6e6;\n  --gray-txt: #555;\n  --sat-txt: #777;\n  --mid-txt: #888;\n  --clrPrm: #0067c0;\n  --scroll: rgb(255 255 255 / 80%);\n  --white: #fefefe;\n  --black: #010101;\n  --active-blue: #0181fd;\n}\n\n.med-txt {\n  color: var(--med-txt);\n}\n\n.light-txt {\n  color: var(--light-txt);\n}\n\n.comp-txt {\n  color: var(--comp-txt);\n}\n\n.gray-txt {\n  color: var(--gray-txt);\n}\n\n.sat-txt {\n  color: var(--sat-txt);\n}\n\n.backblur {\n  backdrop-filter: blur(20px);\n  -webkit-backdrop-filter: blur(20px);\n}\n\n.prtclk {\n  * {\n    pointer-events: none;\n  }\n}\n\n.txt-ovf {\n  display: -webkit-box;\n  -webkit-line-clamp: 1;\n  -webkit-box-orient: vertical;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.wb-line-2 {\n  -webkit-line-clamp: 2;\n}\n\n.wb-line-3 {\n  -webkit-line-clamp: 3;\n}\n\n.wb-line-4 {\n  -webkit-line-clamp: 4;\n}\n\n.status-bar {\n  // position: absolute;\n  height: var(--stbar-h);\n  width: 100%;\n  display: flex;\n  font-size: 0.8em;\n  padding: 1em 1em 0;\n  box-sizing: border-box;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  transition: background-color 200ms ease-in-out;\n  color: var(--txt-col);\n\n  &[data-invert=\"true\"] {\n    color: var(--comp-txt);\n  }\n}\n\n.status-row {\n  display: flex;\n  align-items: center;\n\n  & > div {\n    margin: 0 2px;\n  }\n\n  .battery-level {\n    font-size: 0.9em;\n    height: 14px;\n    margin-right: 0.25em;\n  }\n}\n@keyframes fastfadein {\n  0% {\n    opacity: 0;\n  }\n\n  99% {\n    opacity: 0;\n  }\n\n  100% {\n    opacity: 1;\n  }\n}\n@keyframes pop-up {\n  from {\n    transform: scale(0.5);\n  }\n\n  to {\n    transform: scale(1);\n  }\n}\n@keyframes pop-up2 {\n  from {\n    transform: scale(0.5);\n  }\n\n  to {\n    transform: scale(1);\n  }\n}\n\n.press-in {\n  transition: transform 200ms ease-in-out;\n\n  &:active {\n    transform: scale(0.86);\n  }\n}\n\n.softpress-in {\n  transition: transform 200ms ease-in-out;\n\n  &:active {\n    transform: scale(0.94);\n  }\n}\n\n.quick-trans {\n  transition: transform 100ms ease-in-out;\n}\n\n.flex-column {\n  display: flex;\n  flex-direction: column;\n}\n\n.active-light-lit {\n  transition: all 200ms ease-in-out;\n\n  &:active {\n    background: rgba(254, 254, 254, 0.25);\n  }\n}\n\n.active-dark-lit {\n  transition: all 200ms ease-in-out;\n\n  &:active {\n    background: rgba(0, 0, 0, 0.25);\n  }\n}\n\n.xlit:active {\n  background: rgba(0, 0, 0, 0.12);\n}\n\n.vidCont {\n  .react-video,\n  video {\n    height: 100%;\n  }\n\n  .play-icon {\n    position: absolute;\n    width: 60px;\n    height: 60px;\n    background: rgba(0, 0, 0, 0.5);\n    border-radius: 4em;\n    color: var(--white);\n    z-index: 1;\n    opacity: 0;\n    transition: all 200ms ease-in-out;\n  }\n\n  &:hover .play-icon,\n  .play-icon:hover {\n    opacity: 1;\n  }\n\n  .play-icon.opacity-100 {\n    opacity: 1;\n  }\n}\n\n.video-control-container {\n  width: 100%;\n  display: flex;\n  align-items: center;\n  position: absolute;\n  bottom: 0;\n\n  .video-progress {\n    flex-grow: 1;\n    margin: 0 0.8em;\n  }\n\n  .MuiSlider-rail {\n    background: var(--comp-txt);\n    opacity: 0.8;\n  }\n\n  .MuiSlider-thumb,\n  .MuiSlider-track {\n    opacity: 1;\n  }\n\n  .prog-text {\n    color: var(--comp-txt);\n    font-size: 0.8em;\n    font-weight: 500;\n    padding: 0 0.5em;\n  }\n}\n"
  },
  {
    "path": "src/components/quickpanel/index.js",
    "content": "import React, { useState, useEffect } from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport Hammer, { displayName, propTypes } from '@win11react/react-hammerjs';\nimport Slider from '@mui/material/Slider';\nimport Swiper from 'react-slick';\n\nimport { Icon } from 'components/utils';\nimport StatusBar from 'components/statusbar';\nimport { dispatchAction, dispatchAct } from 'store/actions';\n\nimport './qkpanel.scss';\n\nconst DateObj = (props) => {\n  const date = useSelector((state) => state.global.date)\n  const time = useSelector((state) => state.global.time)\n\n  var datestring = new Date(date.year, date.month, date.day).toLocaleString(\n    \"en-us\",\n    { weekday: \"short\", day: \"numeric\", month: \"long\" }\n  );\n\n  return props.showtime ? (\n    <div className=\"date-day quick-panel-time\" data-extended={props.ext}>\n      <div className=\"text-5xl font-thin\">\n        {time.hours}:{time.minutes}\n      </div>\n      <div className=\"date-day-text\">{datestring}</div>\n    </div>\n  ) : (\n    <div className={\"date-day smooth-trans \" + (props.ext ? \"opacity-0\" : \"\")}>\n      <div className=\"date-day-text\">{datestring}</div>\n    </div>\n  )\n}\n\nexport default function QuickPanel() {\n  const [brightness, setBrightness] = useState(100)\n  const quickpanel = useSelector((state) => state.quickpanel)\n  const display = useSelector((state) => state.global.display)\n\n  const closePanel = (e) => {\n    if (e.target.classList.contains(\"quickpanel-container\")) {\n      dispatchAct({ type: \"quickpanel/close\" })\n    }\n  }\n\n  const handleBright = (e, value) => setBrightness(value)\n  const extendPanel = () => dispatchAct({ type: \"quickpanel/extend\" })\n  const collapsePanel = (e) => {\n    dispatchAct({ type: \"quickpanel/collapse\" })\n  }\n\n  useEffect(() => {\n    dispatchAct({type: \"quickpanel/setLazyBright\", payload: brightness})\n  }, [brightness])\n\n  return (\n    <Hammer\n      onClick={closePanel}\n      onSwipeUp={closePanel}\n      onSwipeDown={extendPanel}\n      direction=\"DIRECTION_ALL\">\n      <div\n        className=\"quickpanel-container backblur\"\n        data-open={quickpanel.open}>\n        <Hammer onSwipeUp={collapsePanel} direction=\"DIRECTION_ALL\">\n          <div className=\"quickpanel\" data-extended={quickpanel.extended}>\n            <StatusBar hidetime={quickpanel.extended} />\n            <DateObj showtime ext={quickpanel.extended && display.height > 600} />\n            <div className=\"date-and-setting\">\n              <DateObj ext={quickpanel.extended} />\n              <Icon fafa=\"faCog\" w={16} />\n            </div>\n            <QuickTool ext={quickpanel.extended} tools={quickpanel.config}/>\n            <div className=\"brightness-input-container flex\">\n              <Icon className=\"mr-2\" mui=\"LightMode\" w={16}/>\n              <Slider value={brightness} defaultValue={brightness}\n                onChange={handleBright} size=\"small\" aria-label=\"Small\"/>\n            </div>\n            <div className=\"quick-panel-bottom-bar\"></div>\n          </div>\n        </Hammer>\n      </div>\n    </Hammer>\n  )\n}\n\nconst QuickTool = (props) => {\n  const [toolCount, setToolCount] = useState(12)\n  const display = useSelector((state) => state.global.display)\n  const settings = {\n    dots: true,\n    arrows: false,\n    infinite: false,\n    speed: 200\n  }\n\n  useEffect(() => {\n    if(display.height > 600) setToolCount(12)\n    else setToolCount(8)\n  },[display.height])\n\n  return (\n    <div className=\"notif-panel\">\n      <div className=\"mini-quick-panel\" data-ext={props.ext}>\n        {props.tools && props.tools.slice(0,6).map((item) => {\n          return (\n            <div className=\"mini-quick-panel-item\" key={item.name} data-active={item.state!=0}>\n              <Icon className=\"mini-quick-icon\" mui={item.icon} w={26} />\n            </div>\n          );\n        })}\n      </div>\n      <Swiper {...settings} className={\"extended-quick\" + (\n        props.ext ? \" extended-quick-open\" : \"\"\n      )}>\n        {props.tools && props.tools.map((temp, idx) => {\n          if(idx%toolCount==0){\n            return (\n              <div className=\"quick-tool-container\" key={idx}>\n                {props.tools.slice(idx, idx+toolCount).map((item,i) => {\n                  return (\n                    <div className=\"quick-tool-item press-in prtclk\" onClick={dispatchAction}\n                      data-action=\"quickpanel/toggleTool\" data-payload={i} key={i}>\n                      <div className=\"mini-quick-panel-item\" data-active={item.state!=0}>\n                        <Icon className=\"mini-quick-icon\" mui={item.icon} w={26}/>\n                      </div>\n                      <div className=\"quick-tool-info\">{item.name}</div>\n                    </div>\n                  );\n                })}\n              </div>\n            )\n          }\n        })}\n      </Swiper>\n    </div>\n  )\n}\n"
  },
  {
    "path": "src/components/quickpanel/qkpanel.scss",
    "content": ".quickpanel-container {\n  position: absolute;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  background: rgba(0, 0, 0, 0);\n  opacity: 0;\n  z-index: -1;\n  transition: 0.3s all ease-in-out;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n\n  &[data-open=\"true\"] {\n    pointer-events: auto;\n    z-index: 1000;\n    opacity: 1;\n    background: rgba(0, 0, 0, 0.2);\n\n    .quickpanel {\n      transform: translateY(0);\n    }\n  }\n}\n\n.quickpanel {\n  width: 100%;\n  max-width: 540px;\n  max-height: 50%;\n  // padding: 0 1.6em 0.5em;\n  padding-bottom: 0.5em;\n  color: var(--med-txt);\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  overflow: hidden;\n\n  & > div {\n    width: 100%;\n    padding: 0 1.6em;\n  }\n\n  .quick-panel-bottom-bar {\n    width: 32px;\n    height: 4px;\n    background: var(--light-txt);\n    border-radius: 10px;\n  }\n\n  .notif-panel {\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  border-radius: 0 0 1em 1em;\n  background: #fefefe;\n  transform: translateY(-100%);\n  transition: all 0.3s ease-in-out;\n\n  &[data-extended=\"true\"] {\n    max-height: 100%;\n  }\n\n  .date-and-setting {\n    display: flex;\n    justify-content: space-between;\n    color: var(--med-txt);\n    margin-bottom: 0.5em;\n    transition: all 200ms ease-in-out;\n  }\n\n  .date-day {\n    font-weight: 600;\n    color: var(--txt-col);\n  }\n\n  .quick-panel-time {\n    max-height: 0;\n    padding: 0;\n    opacity: 0;\n    font-weight: 500;\n    transition: all 200ms linear;\n    display: flex;\n    overflow: hidden;\n    flex-direction: column;\n    align-items: center;\n\n    &[data-extended=\"true\"] {\n      opacity: 1;\n      padding: 2em 0;\n      max-height: 240px;\n    }\n  }\n}\n\n.notif-panel {\n  padding-top: 1em;\n  text-align: center;\n\n  .mini-quick-panel {\n    padding: 0 1.6em;\n    display: flex;\n    width: 100%;\n    justify-content: space-between;\n    transition: all 300ms ease-in-out;\n    margin-bottom: 1em;\n\n    &[data-ext=\"true\"] {\n      position: absolute;\n      width: 150%;\n      opacity: 0;\n      z-index: -1;\n      pointer-events: none;\n    }\n  }\n\n  .mini-quick-panel-item {\n    padding: 8px;\n    background-color: var(--comp-txt);\n    border-radius: 50%;\n\n    .mini-quick-icon {\n      color: var(--sat-txt);\n    }\n\n    &[data-active=\"true\"] {\n      background: var(--active-blue);\n\n      svg {\n        color: #fefefe;\n      }\n    }\n  }\n\n  .extended-quick {\n    max-height: 0;\n    overflow: hidden;\n    opacity: 0;\n    padding: 0 1.6em;\n    pointer-events: none;\n    transition: all 200ms ease-in-out;\n\n    .quick-tool-container {\n      width: 100%;\n      display: grid !important;\n      grid-template-columns: auto auto auto auto;\n      place-items: center;\n      align-items: flex-start;\n      justify-content: space-between;\n      // margin-right: 1em;\n      // margin: 0 1em;\n    }\n\n    .quick-tool-item {\n      max-width: 42px;\n      margin: 0.5em 0;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n\n      .mini-quick-panel-item {\n        margin-bottom: 0.5em;\n      }\n\n      .quick-tool-info {\n        font-size: 0.75em;\n        line-height: 1em;\n        font-weight: 600;\n        width: 200%;\n      }\n    }\n  }\n\n  .extended-quick-open {\n    max-height: 800px;\n    pointer-events: auto;\n    // overflow: visible;\n    opacity: 1;\n    animation: fastfadein 200ms linear;\n  }\n\n  .slick-list {\n    margin: 0 -2em;\n  }\n\n  .slick-slide > div {\n    margin: 0 2em;\n  }\n\n  .slick-dots {\n    position: relative;\n    bottom: 0;\n\n    li {\n      width: 6px;\n    }\n  }\n}\n"
  },
  {
    "path": "src/components/statusbar.js",
    "content": "import React, {useState, useEffect, useRef} from 'react';\nimport { useSelector } from 'react-redux';\nimport Hammer from '@win11react/react-hammerjs';\n\nimport parse from 'color-parse';\nimport rgba from 'color-rgba';\n\nimport { Icon } from 'components/utils';\nimport { dispatchAction } from 'store/actions';\nimport { NetworkIcon, BatteryIcon } from 'components/icons';\n\nimport './main.scss';\n\nconst StatusBar = (props) => {\n  const [invert, setInvert] = useState(props.invert);\n  const statusBar = useRef();\n  const battery = useSelector((state) => state.global.battery);\n  const time = useSelector((state) => state.global.time);\n\n  const istransparent = (bgcolor)=>{\n    var colors = parse(bgcolor)\n    return colors.alpha < 0.1;\n  }\n\n  useEffect(()=>{\n    if(props.invert!=null){\n      setInvert(props.invert)\n    }else if(props.bg || (invert && !props.bg)){\n      if(statusBar.current){\n        var bgcolor = getComputedStyle(statusBar.current).getPropertyValue('background-color');\n        if(!istransparent(bgcolor)){\n          var arr = rgba(bgcolor),\n              avg = (arr[0]+arr[1]+arr[2])/3\n\n          if(avg<128) setInvert(true)\n          else setInvert(false)\n        }else{\n          setInvert(false)\n        }\n      }\n    }\n  }, [props.bg])\n\n  return (\n    <Hammer onSwipeDown={dispatchAction} direction=\"DIRECTION_ALL\">\n      <div className=\"status-bar\" data-action=\"quickpanel/open\" style={{\n        backgroundColor: props.bg\n      }} data-invert={invert}>\n        <div className=\"hidden\" style={{backgroundColor: props.bg}} ref={statusBar}></div>\n        <div className={\n            \"status-time smooth-trans\" + (props.hidetime ? \" opacity-0\" : \"\")\n          }>{time.hours}:{time.minutes}</div>\n        <div className=\"status-row\">\n          <Icon fafa=\"faWifi\" w={12} fill=\"#444\" />\n          <NetworkIcon w={10} fill={invert?\"#ddd\":\"#222\"} filldim=\"#888\" />\n          <div className=\"flex items-center text-xs font-bold\">\n            <div className=\"battery-level\">\n              {Math.round(battery.level * 100) + \"%\"}\n            </div>\n            <BatteryIcon w={6} h={12} fill={invert?\"#ddd\":\"#222\"} battery={battery}\n              filldim={invert?\"#555\":\"#aaa\"} cfill={invert?\"#010101\":\"#fefefe\"}/>\n          </div>\n        </div>\n      </div>\n    </Hammer>\n  );\n};\n\nexport default StatusBar;\n"
  },
  {
    "path": "src/components/utils.js",
    "content": "import React, { useState, useEffect, useRef } from 'react';\nimport {useSelector} from 'react-redux';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport ReactPlayer from 'react-player';\n\nimport Slider from '@mui/material/Slider';\n\nimport { dispatchAction } from 'store/actions';\nimport * as FaIcons from '@fortawesome/free-solid-svg-icons';\nimport * as FaRegIcons from '@fortawesome/free-regular-svg-icons';\nimport * as MUIcons from '@mui/icons-material';\nimport * as AllIcons from 'components/icons';\n\nconst {round, floor, random, min, max, abs} = Math;\n\nexport const MaterialIcon = (props) => {\n  var icon = props.mui;\n  if (props.out) icon += \"Outlined\";\n  if (props.round) icon += \"Rounded\";\n  if (props.twotone) icon += \"TwoTone\";\n  if (props.sharp) icon += \"Sharp\";\n\n  // const Icon = <div></div>\n  const MuiIcon = MUIcons[icon];\n  return (\n    <MuiIcon\n      className={\n        props.flip? \"flip-true\": \"\" +\n        (props.invert? \" invert-true\": \"\") +\n        (props.rounded? \" rounded-true\": \"\")\n      } style={{\n        width: props.w,\n        height: props.h || props.w,\n        color: props.color,\n        margin: props.margin,\n      }}\n    />\n  );\n};\n\nexport const Icon = (props) => {\n  var src = `img/icon/${props.ui ? \"ui/\" : \"\"}${props.src}`;\n  if (props.src && !props.src.includes(\".\")) {\n    src += \".png\";\n  }\n\n  if (props.ext || (props.src && props.src.startsWith(\"http\"))) {\n    src = props.src;\n  }\n\n  var dataset = {}\n  Object.entries(props).forEach(([key, value]) => {\n    if(key.includes(\"data-\")){\n      dataset[key] = value;\n    }\n  });\n\n  var classname = `uicon prtclk ${props.className || \"\"}`.trim()\n  var styles = {\n    borderRadius: props.radii\n  }\n\n  const label = props.label!=null && <span>{props.label}</span>\n\n  if (props.fafa) {\n    return (\n      <div className={classname} {...dataset} style={styles}\n        onClick={props.onClick || (props.action && dispatchAction)}\n        data-action={props.action} data-payload={props.payload}>\n        <FontAwesomeIcon\n          data-flip={props.flip}\n          data-invert={props.invert}\n          data-rounded={props.rounded}\n          style={{\n            width: props.w,\n            height: props.h || props.w,\n            color: props.color,\n            margin: props.margin\n          }}\n          icon={!props.reg ? FaIcons[props.fafa] : FaRegIcons[props.fafa]}\n        />\n        {label}\n      </div>\n    );\n  } else if (props.mui) {\n    return (\n      <div className={classname} {...dataset} style={styles}\n        onClick={props.onClick || (props.action && dispatchAction)}\n        data-action={props.action} data-payload={props.payload}>\n        <MaterialIcon {...props} />\n        {label}\n      </div>\n    );\n  }else if (props.icon) {\n    var CustomIcon = AllIcons[props.icon];\n    return (\n      <div className={classname} {...dataset} style={styles}\n        onClick={props.onClick || (props.action && dispatchAction)}\n        data-action={props.action} data-payload={props.payload}>\n        <CustomIcon {...props} />\n        {label}\n      </div>\n    );\n  } else {\n    return (\n      <div className={classname} data-active={props.active} {...dataset}\n        data-action={props.action} data-payload={props.payload}\n        onClick={props.onClick || dispatchAction} style={styles}>\n        <img width={props.w} height={props.h} data-flip={props.flip}\n          data-invert={props.invert} data-rounded={props.rounded}\n          src={src} style={{ margin: props.margin}}\n          alt={props.alt || \"\"}/>\n          {label}\n      </div>\n    );\n  }\n};\n\nexport const Image = (props) => {\n  var src = `img/${(props.dir?props.dir+\"/\":\"\")+props.src}`;\n  if (props.src && !props.src.includes(\".\")) {\n    src += \".png\";\n  }\n\n  if (props.ext || (props.src && props.src.startsWith(\"http\"))) {\n    src = props.src;\n  }\n\n  const errorHandler = (e)=>{\n    if(props.err) e.target.src = props.err\n  }\n\n  var dataset = {}\n  Object.entries(props).forEach(([key, value]) => {\n    if(key.includes(\"data-\")){\n      dataset[key] = value;\n    }\n  });\n\n  return (\n    <div className={`imageCont prtclk ${props.className||''}`} id={props.id} style={{\n      backgroundImage: props.back && `url(${src})`\n    }} data-back={props.back} onClick={props.onClick || (props.action && dispatchAction)}\n      data-action={props.action} data-payload={props.payload} {...dataset}>\n        {!props.back?<img\n          width={props.w}\n          height={props.h}\n          data-free={props.free}\n          data-var={props.var}\n          loading={props.lazy && \"lazy\"}\n          src={src} alt=\"\" onError={errorHandler}/>:null}\n    </div>\n  )\n}\n\nexport const isValidURL = (str)=>{\n  var res = str.match(/(http(s)?:\\/\\/.)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)/g);\n  return (res !== null)\n};\n\nconst formatseconds = (sec)=>{\n  if (!sec) return \"00:00\";\n  var res = floor(sec / 60);\n  res += ':';\n  sec %= 60;\n  if (sec < 10) res += \"0\";\n  res += sec;\n\n  return res;\n}\n\nexport const Video = (props) => {\n  const [play, setPlay] = useState(props.autoplay);\n  const [prog, setProg] = useState(0); // time elapsed\n  const [perProg, setPerProg] = useState(0); // time elapsed in %\n  const vidplayer = useRef();\n\n  var src = `img/${(props.dir?props.dir+\"/\":\"\")+props.src}`;\n  if (props.src && !props.src.includes(\".\")) src += \".mp4\";\n\n  if (props.ext || (props.src && props.src.includes(\"http\"))) {\n    src = props.src;\n  }\n\n  const className = `vidCont ${(props.inactive || props.clickToggle)?'prtclk':''} ${props.className||''}`.trim()\n  var dataset = {}\n  Object.entries(props).forEach(([key, value]) => {\n    if(key.includes(\"data-\")){\n      dataset[key] = value\n    }\n  });\n\n  const handlePause = (e) => setPlay(false)\n  const handlePlay = (e) => setPlay(true)\n  const togglePlay = (e) => setPlay(!play)\n\n  const handleProg = (e)=>{\n    setProg(floor(e.playedSeconds))\n    setPerProg(e.played)\n  }\n\n  const handleSliderChange = (e)=>{\n    if(!vidplayer.current) return\n\n    var ip = e.target.value/100\n    vidplayer.current.seekTo(ip, 'fraction')\n    setPerProg(ip);\n    setProg(floor(ip*vidplayer.current.getDuration()));\n  }\n\n  return (\n    <div className={className} id={props.id} onClick={ props.onClick ||\n        (props.action && dispatchAction) || (props.clickToggle && togglePlay)\n      } data-action={props.action} data-payload={props.payload} {...dataset} tabIndex=\"1\">\n        {!props.playIcon && play &&\n          <Icon className=\"play-icon\" mui=\"Pause\" round w={48} onClick={handlePause}/>}\n        {!props.playIcon && !play &&\n          <Icon className=\"play-icon opacity-100\" mui=\"PlayArrow\" round w={48} onClick={handlePlay}/>}\n        {props.playIcon}\n        <ReactPlayer className=\"react-video\" url={src}\n          width={props.w || \"auto\"} height={props.h || \"auto\"} ref={vidplayer}\n          playing={props.play || play} volume={props.muted ? 0 : 1} controls={props.controls}\n          onPlay={props.onPlay || handlePlay} onPause={props.onPause || handlePause}\n          onProgress={props.onProgress || handleProg} onEnded={props.onEnded || handlePause}/>\n        {props.cstmctrl && (\n          <div className=\"video-control-container\">\n            <span className=\"prog-text\">{formatseconds(prog)}</span>\n            <Slider size=\"small\"\n              className=\"video-progress\"\n              value={perProg*100}\n              defaultValue={0}\n              onChange={handleSliderChange}\n            />\n            <span className=\"prog-text\">{formatseconds(floor(prog/perProg))}</span>\n          </div>\n        )}\n    </div>\n  )\n}\n\nexport const LazyComponent = ({ show, children }) => {\n  const [loaded, setLoad] = useState(false);\n\n  useEffect(() => {\n    if (show && !loaded) setLoad(true);\n  }, [show]);\n\n  return show || loaded ? <>{children}</> : null;\n};\n"
  },
  {
    "path": "src/components/widgets/index.js",
    "content": "import React, { useState, useEffect } from 'react'\nimport { useSelector, useDispatch } from 'react-redux'\nimport Calendar from 'react-calendar'\n\nimport {Icon} from 'components/utils'\nimport {dispatchAction, dispatchAct, openAppPage} from 'store/actions';\nimport './widget.scss'\n\nconst ClockDate = (props)=>{\n  const date = useSelector((state) => state.global.date);\n  var datestring = new Date(date.year, date.month, date.day).toLocaleString(\"en-us\",{\n    weekday: \"short\", day: \"numeric\", month: props.datemin?\"short\":\"long\"\n  });\n\n  var classNameString = props.className || \"\"\n  return <div className={\"clock-date \" + classNameString}>{datestring}</div>\n}\n\nexport const GoogleSearch = () => {\n\n  const handleClick = () => {\n    openAppPage(\"google\",\"google.search\")\n  }\n\n  return (\n    <div className=\"google-search-container press-in\" onClick={handleClick}>\n      <div className=\"google-input-container flex justify-between items-center\">\n        <Icon src=\"apps/google\" w={26}/>\n        <Icon src=\"apps/mic\" w={24}/>\n      </div>\n    </div>\n  );\n};\n\nexport const AnalogClock = () => {\n  const time = useSelector((state) => state.global.time);\n\n  const calculateAngles = ()=>{\n    var hr = time.hours >= 12 ? time.hours - 12 : time.hours,\n        mn = time.minutes\n\n    hr *= 30\n    hr += mn/2\n    mn *= 6\n    return [hr, mn]\n  }\n\n  return (\n    <div className=\"analog-clock-container\">\n      <div className=\"clock-body\">\n        <div className=\"minute-container\" style={{\n          transform: `rotateZ(${calculateAngles()[1]}deg)`\n        }}>\n          <div className=\"minute-hand\"></div>\n        </div>\n        <div className=\"hour-container\" style={{\n          transform: `rotateZ(${calculateAngles()[0]}deg)`\n        }}>\n          <div className=\"hour-hand\"></div>\n        </div>\n        <div className=\"clock-center\"></div>\n      </div>\n      <ClockDate/>\n    </div>\n  );\n};\n\nexport const MinimalClock = () => {\n  const time = useSelector((state) => state.global.time);\n\n  return (\n    <div className=\"digital-time-container\">\n      <div className=\"flex items-baseline\">\n        <div className=\"text-4xl\">{time.hours}:{time.minutes}</div>\n        <div className=\"text-xs ml-1\">{time.abb}</div>\n      </div>\n      <ClockDate className=\"text-sm mt-2\"/>\n    </div>\n  );\n};\n\nexport const MinimalVertClock = () => {\n  const time = useSelector((state) => state.global.time);\n  const fillZero = (x)=>{\n    return (x<9?\"0\":\"\") + x\n  }\n\n  return (\n    <div className=\"vert-time-container\">\n      <div className=\"flex flex-col\">\n        <div className=\"text-6xl font-thin\">{fillZero(time.hours)}</div>\n        <div className=\"text-6xl font-thin\">{time.minutes}</div>\n      </div>\n      <ClockDate className=\"text-sm mt-2\" datemin/>\n    </div>\n  );\n};\n\nexport const DayCountdown = ()=>{\n  return (\n    <div className=\"countdown-container\">\n      <div className=\"countdown-topic text-xs\">Mom's B'day</div>\n      <div className=\"quant-left text-2xl\">215</div>\n      <div className=\"quant-unit text-xs\">days left</div>\n    </div>\n  )\n}\n\nexport const WideCalender = ()=>{\n  const date = useSelector((state) => state.global.date);\n  var datemonth = new Date(date.year, date.month, date.day).toLocaleString(\"en-us\",{month: \"long\"});\n\n  const formatShortWeekday = (label, date)=>{\n    return date.toLocaleString(\"en-us\",{weekday: \"short\"})[0]\n  }\n\n  return (\n    <div className=\"calender-container medScroll\">\n      <div className=\"calendar-month text-xl pb-1\">{datemonth}</div>\n      <div className=\"flex\">\n        <Calendar\n          showNavigation={false}\n          showNeighboringMonth={false}\n          formatShortWeekday={formatShortWeekday}/>\n\n        <div className=\"calender-events\">\n          <div className=\"event-container\">\n            <div className=\"event-name text-sm\">Disneyland</div>\n            <div className=\"event-time text-xs\">All day</div>\n          </div>\n          <div className=\"event-container\">\n            <div className=\"event-name text-sm\">Meeting</div>\n            <div className=\"event-time text-xs\">11:00 AM - 2:00 PM</div>\n          </div>\n          <div className=\"event-container\">\n            <div className=\"event-name text-sm\">Business</div>\n            <div className=\"event-time text-xs\">3:30 PM - 8:00 PM</div>\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport const WideWeather = ()=>{\n  const date = useSelector((state) => state.global.date);\n  const weather = useSelector((state) => state.widget.weather);\n  var datemonth = new Date(date.year, date.month, date.day).toLocaleString(\"en-us\",{month: \"long\"});\n  var iconurl = \"https://www.metaweather.com/static/img/weather/\"\n\n  return (\n    <div className=\"weather-container medScroll\">\n      <div className=\"city-container\">\n        <Icon mui=\"LocationOn\" w={18}/>\n        <span>{weather.city}</span>\n      </div>\n      <ClockDate className=\"weather-date\"/>\n      <div className=\"main-weather\">\n        <Icon src={iconurl+weather.icon+\".svg\"} ext w={48}/>\n        <div className=\"today-temperature\">{weather.temperature}°</div>\n      </div>\n      <div className=\"weather-pred-container\">\n        {weather && weather.predictions.map((pred, i)=>{\n          return(\n            <div className=\"weather-pred\" key={i}>\n              <Icon src={iconurl + pred.icon + \".svg\"} ext w={32}/>\n              <div className=\"pred-day\">{pred.day}</div>\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nexport const ShortWeather = ()=>{\n  const date = useSelector((state) => state.global.date);\n  const weather = useSelector((state) => state.widget.weather);\n  var datemonth = new Date(date.year, date.month, date.day).toLocaleString(\"en-us\",{month: \"long\"});\n  var iconurl = \"https://www.metaweather.com/static/img/weather/\"\n\n  return (\n    <div className=\"weather-container short-weather-container medScroll\">\n      <div className=\"main-weather\">\n        <Icon src=\"weather/clear-sky\" w={56}/>\n        <div className=\"today-temperature\">{weather.temperature}°</div>\n      </div>\n      <div className=\"city-container\">\n        <Icon mui=\"LocationOn\" w={18}/>\n        <span>{weather.city}</span>\n      </div>\n      <ClockDate className=\"weather-date\"/>\n    </div>\n  )\n}\n"
  },
  {
    "path": "src/components/widgets/widget.scss",
    "content": ".google-search-container {\n  width: 100%;\n  padding: 0 1em;\n  display: flex;\n}\n\n.google-input-container {\n  background: #fefefe;\n  border-radius: 200px;\n  padding: 0.8em;\n  flex-grow: 1;\n}\n\n.analog-clock-container {\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n\n  .clock-body {\n    width: 60%;\n    aspect-ratio: 1 / 1;\n    max-width: 160px;\n    max-height: 160px;\n    background: #fafafa;\n    border-radius: 50%;\n    position: relative;\n    box-shadow: 0 -4px 16px rgba(36, 36, 36, 0.1), 0 4px 16px rgba(36, 36, 36, 0.1);\n\n    .clock-center {\n      position: absolute;\n      background: #333;\n      inset: 50%;\n      width: 8px;\n      height: 8px;\n      margin-top: -4px;\n      margin-left: -4px;\n      border-radius: 50%;\n    }\n\n    .hour-container,\n    .minute-container {\n      width: 100%;\n      height: 100%;\n      position: absolute;\n      inset: 0;\n      display: grid;\n      place-items: center;\n    }\n\n    .hour-hand,\n    .minute-hand {\n      width: 4px;\n      border-radius: 8px;\n      transform: translateY(-50%);\n    }\n\n    .hour-hand {\n      height: 20%;\n      background: #444;\n    }\n\n    .minute-hand {\n      height: 40%;\n      background: #888;\n    }\n  }\n\n  .clock-date {\n    font-size: 0.9em;\n    margin-top: 0.5em;\n    color: var(--med-txt);\n  }\n}\n\n.digital-time-container,\n.vert-time-container {\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  color: var(--med-txt);\n}\n\n.vert-time-container > div {\n  width: 100%;\n  padding: 0 1em;\n}\n\n.cell-container {\n  // box-sizing: border-box;\n  // border: solid 1px red;\n}\n\n.calender-container {\n  box-sizing: border-box;\n  background: #fefefe;\n  border-radius: 1em;\n  padding: 0.6em 1em;\n  position: absolute;\n  inset: 0.5em 1em;\n  overflow-x: hidden;\n  overflow-y: scroll;\n\n  .react-calendar {\n    width: 66%;\n\n    .react-calendar__month-view__days__day--weekend {\n      color: red;\n    }\n\n    .react-calendar__tile--now {\n      color: #fefefe;\n      position: relative;\n      transform: translateX(-36%);\n\n      abbr {\n        position: absolute;\n        inset: 0 0.3em;\n        text-align: center;\n        font-weight: 400;\n        background: #444;\n        border-radius: 6px;\n      }\n    }\n\n    abbr {\n      display: block;\n      text-decoration: none;\n      font-size: 0.72em;\n      font-weight: 600;\n      padding: 0.2em 0;\n      text-align: left;\n    }\n  }\n\n  .calender-events {\n    display: grid;\n    grid-template-rows: 1fr 1fr 1fr;\n    width: 33%;\n\n    .event-container {\n      color: var(--med-txt);\n      border: 0 solid var(--comp-txt);\n      border-left-width: 2px;\n      padding-left: 0.5em;\n      position: relative;\n\n      &::after {\n        content: \"\";\n        position: absolute;\n        top: -2px;\n        left: -4px;\n        width: 6px;\n        height: 6px;\n        border-radius: 20px;\n        background: #277beb;\n      }\n\n      .event-time {\n        height: 16px;\n        color: var(--sat-txt);\n        font-weight: 300;\n        overflow: hidden;\n      }\n    }\n  }\n}\n\n.countdown-container {\n  position: absolute;\n  inset: 0.5em 1em;\n  text-align: center;\n  background: #fefefe;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  padding: 0.5em;\n  border-radius: 1em;\n}\n\n.weather-container {\n  box-sizing: border-box;\n  background: #fefefe;\n  border-radius: 1em;\n  padding: 0.6em 1em;\n  position: absolute;\n  inset: 0.5em 1em;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  color: var(--med-txt);\n  letter-spacing: 1px;\n  overflow-x: hidden;\n  overflow-y: scroll;\n\n  .city-container {\n    display: flex;\n\n    span {\n      font-size: 1rem;\n    }\n  }\n\n  .weather-date {\n    font-size: 0.9em;\n    font-weight: 100;\n    color: var(--gray-txt);\n  }\n\n  .main-weather {\n    display: flex;\n    align-items: center;\n    flex-grow: 1;\n  }\n\n  .today-temperature {\n    font-size: 3em;\n    font-weight: 100;\n    margin-left: 0.3em;\n  }\n\n  .weather-pred-container {\n    display: flex;\n    justify-content: space-between;\n\n    .weather-pred {\n      margin: 0 0.8em;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    .pred-day {\n      font-size: 0.8em;\n    }\n  }\n}\n\n.short-weather-container {\n  .today-temperature {\n    font-size: 2.5em;\n    margin-left: 0.1em;\n  }\n\n  .main-weather .uicon {\n    height: 100%;\n  }\n}\n"
  },
  {
    "path": "src/containers/apps/google/google.scss",
    "content": ".google-home, .google-spage, .search-frame {\n  padding: 1em 0;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  box-sizing: border-box;\n}\n\n.google-land, .google-spage{\n  .namelogo {\n    width: 100%;\n  }\n\n  .search-box-container {\n    width: 96%;\n    padding: 0.5em 1em;\n    margin-top: 2em;\n    margin-right: 2%;\n    margin-bottom: 1em;\n    border-radius: 2em;\n    box-shadow: 1px 2px 8px rgba(74, 71, 71, 0.15);\n  }\n\n  .search-input {\n    display: flex;\n    align-items: center;\n\n    svg {\n      color: var(--light-txt);\n    }\n\n    .search-inp {\n      flex-grow: 1;\n\n      input {\n        padding: 0.25em 0.5em;\n      }\n\n      fieldset {\n        display: none;\n      }\n    }\n  }\n\n  .news-container {\n    padding: 0 0.5em;\n\n    .news-box {\n      margin: 0.6em 0;\n      color: var(--mid-txt);\n    }\n\n    .news-title {\n      font-size: 0.96em;\n      color: var(--med-txt);\n    }\n\n    .imageCont {\n      border-radius: 0.8em;\n      overflow: hidden;\n      margin-bottom: 0.5em;\n    }\n  }\n}\n\n.google-spage{\n  .search-box-container{\n    box-sizing: border-box;\n    padding: 0.5em 0.25em;\n    margin: 0;\n    width: 90%;\n    border: 0 solid var(--comp-txt);\n    border-radius: 0;\n    border-bottom-width: 2px;\n    box-shadow: none;\n\n    .search-inp input{\n      padding: 0.25em 1em;\n    }\n  }\n\n  .search-suggestions{\n    flex-grow: 1;\n    width: 100%;\n    overflow-y: scroll;\n    margin-top: 0.5em;\n    color: var(--light-txt);\n\n    .trending-search{\n      margin-top: 1em;\n\n      .sugg-title{\n        margin-bottom: 0.5em;\n      }\n    }\n\n    .sugg-title{\n      padding: 0 0.5em;\n      margin: 0 1.5em;\n      font-size: 0.68em;\n      letter-spacing: 1px;\n      font-weight: 600;\n    }\n\n    .sugg-box{\n      display: flex;\n      padding: 0.5em 1.5em;\n\n      span{\n        margin-left: 1em;\n        font-weight: 500;\n        color: var(--txt-col);\n      }\n    }\n  }\n}\n\n.search-frame{\n  padding: 0;\n\n  iframe{\n    width: 100%;\n    height: 100%;\n  }\n}\n"
  },
  {
    "path": "src/containers/apps/google/index.js",
    "content": "import React, {useState, useEffect} from 'react'\nimport {useSelector, useDispatch} from 'react-redux'\n\nimport TextField from '@mui/material/TextField'\n\nimport {Icon, Image} from 'components/utils'\nimport {dispatchAction, dispatchAct} from 'store/actions'\n\nimport './google.scss'\nimport newsdata from './news.json'\n\nexport const GoogleApp = () => {\n  const app = useSelector(state => state.home.apps.google || {})\n  const home = useSelector(state => state.home)\n  const show = home.ishome==false && home.stack.at(-1)==app.payload\n  const pagetree = app && app.pagetree || {\n    \"main\": {\n      \"search\" : {},\n      \"result\" : {}\n    }\n  }\n\n  useEffect(()=>{\n    if(app && !app.pagetree){\n      dispatchAct({type: \"home/setApp\", payload: {\n        id: app.payload,\n        data: {\n          ... app,\n          pagetree: pagetree,\n          path: ['main']\n        }\n      }})\n    }\n  }, [app])\n\n  return <AppContainer app={app} show={show}/>\n}\n\nconst AppContainer = ({app, show}) => {\n  const [searchtxt, setTxt] = useState('')\n  const clstring = `${app.payload}-wrapper`\n  const path = app.path || ['main']\n\n  const handlleReset = () => setTxt('')\n  const openResults = () => dispatchAct({\n    type: \"home/navApp\",\n    payload: \"google.result\"\n  })\n\n  const handleTxtChange = (e) => setTxt(e.target.value)\n  const handleSuggClk = (e) => {\n    setTxt(e.target.innerText)\n    openResults()\n  }\n\n  const handleSearch = (e) => {\n    if(e.key == \"Enter\" && searchtxt.length) openResults()\n  }\n\n  const checkstate = (comp) => {\n    return path.includes(comp) ? (\n      path.at(-1) == comp ? 1 : 2\n    ) : 0;\n  }\n\n  const sdata = {\n    \"sugg\": [\"videos\", \"old songs\", \"hd wallpapers\", \"love\", \"new movies\", \"new songs\", \"cool photos\", \"images\"],\n    \"trend\": [\"T20 World Cup\", \"Squid Game\", \"Afghanistan\", \"Ethereum Price\", \"Baked oats\", \"Battlefield 2042\", \"Black Widow\"]\n  }\n\n  return (\n    <div className={\"app-wrapper \"+clstring} id={clstring} data-open={show}>\n      <div className=\"app-inner-wrapper gg-inner-wrapper\">\n        {checkstate('main')==1 && (\n          <div className=\"google-home overflow-y-scroll h-full\">\n            <div className=\"google-land flex flex-col items-end\">\n              <Image className=\"rounded rounded-full\" src=\"blue.jpg\" w={28}/>\n              <Image className=\"namelogo\" dir=\"asset/other\" src=\"googlename\" w={120}/>\n              <div className=\"search-box-container press-in prtclk\" onClick={dispatchAction}\n                data-action=\"home/navApp\" data-payload=\"google.search\">\n                <div className=\"search-input\">\n                  <Icon mui=\"Search\" w={24}/>\n                  <TextField className=\"search-inp\" placeholder=\"Search...\" disabled/>\n                  <Icon src=\"apps/mic\" w={20}/>\n                </div>\n              </div>\n              <div className=\"news-container\">\n                {newsdata.articles.map((article,i) => {\n                  return (\n                    <div className=\"news-box\" key={i}>\n                      <Image src={article.urlToImage}/>\n                      <div className=\"news-title txt-ovf wb-line-3\">\n                        {article.title}\n                      </div>\n                      <div className=\"flex mt-2 px-1 mb-8\">\n                        <Icon className=\"rounded-full\" src={new URL(article.url).origin + \"/favicon.ico\"} w={14}/>\n                        <span className=\"text-xs light-txt font-thin ml-2\">{article.source.name}</span>\n                        <div className=\"flex-grow\"></div>\n                        <Icon className=\"mr-4\" mui=\"Share\" w={16}/>\n                        <Icon mui=\"MoreVert\" w={18}/>\n                      </div>\n                    </div>\n                  )\n                })}\n              </div>\n            </div>\n          </div>\n        )}\n        {checkstate('search')==1 && (\n          <div className=\"google-spage\">\n            <div className=\"search-box-container\">\n              <div className=\"search-input\">\n                <Icon src=\"apps/google\" w={26}/>\n                <TextField className=\"search-inp\" placeholder=\"Search...\" autoFocus\n                  value={searchtxt} onChange={handleTxtChange} onKeyPress={handleSearch}/>\n                  {searchtxt.length ? (\n                    <Icon mui=\"Close\" w={20} onClick={handlleReset}/>\n                  ) : <Icon src=\"apps/mic\" w={20}/>}\n              </div>\n            </div>\n            <div className=\"search-suggestions thinScroll\">\n              <div className=\"try-search\">\n                <div className=\"sugg-title\">TRY SEARCHING FOR</div>\n                {sdata.sugg.map((x,i) => (\n                  <div className=\"sugg-box active-dark-lit xlit prtclk\"\n                    onClick={handleSuggClk} key={i}>\n                    <Icon mui=\"Search\" w={20}/>\n                    <span>{x}</span>\n                    <div className=\"flex-grow\"></div>\n                    <Icon mui=\"CallMade\" flip w={20}/>\n                  </div>\n                ))}\n              </div>\n              <div className=\"trending-search\">\n                <div className=\"sugg-title\">TRENDING SEARCHES</div>\n                {sdata.trend.map((x,i) => (\n                  <div className=\"sugg-box active-dark-lit xlit prtclk\"\n                    onClick={handleSuggClk} key={i}>\n                    <Icon mui=\"TrendingUp\" w={20}/>\n                    <span>{x}</span>\n                  </div>\n                ))}\n              </div>\n            </div>\n          </div>\n        )}\n        {checkstate('result')==1 && (\n          <div className=\"search-frame\">\n            <iframe src={'https://www.google.com/search?igu=1&q='+searchtxt} frameBorder=\"0\"></iframe>\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "src/containers/apps/google/news.json",
    "content": "{\n  \"articles\": [{\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NDTV News\"\n      },\n      \"author\": \"NDTV Sports Desk\",\n      \"title\": \"IPL 2022, SRH vs KKR Live Score: Kane Williamson, Rahul Tripathi Rebuild For SRH After Early Wicket - NDTV Sports\",\n      \"description\": \"IPL 2022, SRH vs KKR Live Updates: Chasing a target of 176, SunRisers Hyderabad (SRH) lost both of their openers in the powerplay against Kolkata Knight Riders (KKR) in match 25 of IPL 2022 at the Brabourne Stadium in Mumbai.\",\n      \"url\": \"https://sports.ndtv.com/ipl-2022/ipl-2022-srh-vs-kkr-live-score-updates-2891194\",\n      \"urlToImage\": \"https://c.ndtvimg.com/2022-04/f6386o_kkr-bcci_625x300_15_April_22.jpg?im=FeatureCrop,algorithm=dnn,width=1200,height=675\",\n      \"publishedAt\": \"2022-04-15T16:31:54Z\",\n      \"content\": \"IPL 2022, SRH vs KKR Live Updates: Chasing a target of 176, SunRisers Hyderabad (SRH) lost both of their openers in the powerplay against Kolkata Knight Riders (KKR) in match 25 of IPL 2022 at the Br… [+1230 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NDTV News\"\n      },\n      \"author\": null,\n      \"title\": \"WHO Monitors Hepatitis Of Unknown Origin In UK Children - NDTV\",\n      \"description\": \"The World Health Organization said Friday it was monitoring cases of hepatitis of unknown origin in dozens of children in Britain, some of whom required a liver transplant.\",\n      \"url\": \"https://www.ndtv.com/world-news/who-monitors-hepatitis-of-unknown-origin-in-uk-children-2891847\",\n      \"urlToImage\": \"https://i.ndtvimg.com/i/2017-09/hepatitis-action-plan-to-come-in-october_650x400_41505196638.jpg\",\n      \"publishedAt\": \"2022-04-15T16:17:52Z\",\n      \"content\": \"The infection mainly affected children aged under 10.\\r\\nLondon, United Kingdom: The World Health Organization said Friday it was monitoring cases of hepatitis of unknown origin in dozens of children i… [+1589 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NDTV News\"\n      },\n      \"author\": null,\n      \"title\": \"Karnataka Minister KS Eshwarappa, Named In Suicide Case, Resigns: Report - NDTV\",\n      \"description\": \"After a meeting with Chief Minister Basavaraj Bommai at his residence in Bengaluru, Mr Eshwarappa submitted his resignation.\",\n      \"url\": \"https://www.ndtv.com/india-news/karnataka-minister-ks-eshwarappa-named-in-suicide-case-resigns-2891676\",\n      \"urlToImage\": \"https://c.ndtvimg.com/2022-04/88a73te8_ks-eswarappa-with-basavaraj-bommai-650_650x400_15_April_22.jpg\",\n      \"publishedAt\": \"2022-04-15T15:46:11Z\",\n      \"content\": \"\\\"I am also confident that I will come out clean,\\\" KS Eshwarappa said before resigning.\\r\\nBengaluru: BJP stalwart and Karnataka minister KS Eshwarappa, caught in a huge controversy following allegation… [+3084 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Indian Express\"\n      },\n      \"author\": \"Express News Service\",\n      \"title\": \"At Delhi BJP office, 8 accused of attacking Kejriwal residence are garlanded - The Indian Express\",\n      \"description\": \"AAP MLA Atishi lashed out at the BJP, saying they had sent a message to its workers across the country that they will be felicitated if they indulge in “hooliganism and vandalism”.\",\n      \"url\": \"https://indianexpress.com/article/cities/delhi/delhi-bjp-office-8-accused-attacking-kejriwal-residence-are-garlanded-7871100/\",\n      \"urlToImage\": \"https://images.indianexpress.com/2022/04/BJYM.jpg\",\n      \"publishedAt\": \"2022-04-15T15:35:42Z\",\n      \"content\": \"Eight men who were arrested and later released on bail in connection with the attack on Chief Minister Arvind Kejriwals residence were on Thursday felicitated at the Delhi BJP office by the partys st… [+2134 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Indian Express\"\n      },\n      \"author\": \"Man Aman Singh Chhina\",\n      \"title\": \"Explained: Why is the Black Sea crucial to Russia, and the loss of the ‘Moskva’ a significant blow - The Indian Express\",\n      \"description\": \"The sinking of the warship Moskva, the 600-foot, 12,500-tonne flagship of the Russian Black Sea Fleet — whether due to a Ukrainian missile strike or, as Russia claims, a fire on board — is a serious setback for Russia.\",\n      \"url\": \"https://indianexpress.com/article/explained/everyday-explainers/explained-russia-warship-moksva-black-sea-7870946/\",\n      \"urlToImage\": \"https://images.indianexpress.com/2022/04/Russia-warship-ex.jpg\",\n      \"publishedAt\": \"2022-04-15T15:35:22Z\",\n      \"content\": \"The sinking of the warship Moskva, the 600-foot, 12,500-tonne flagship of the Russian Black Sea Fleet whether due to a Ukrainian missile strike or, as Russia claims, a fire on board is a serious setb… [+6665 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Indian Express\"\n      },\n      \"author\": \"Entertainment Desk\",\n      \"title\": \"KGF 2 box office collection day 1: Yash-starrer registers biggest-ever opening day in Hindi belt, earns Rs 134.5 crore in India - The Indian Express\",\n      \"description\": \"Yash's KGF 2 has received a massive opening across south Indian states. While the film dominated the box office in Karnataka, it also received a huge launch in Tamil Nadu, Kerala and the Telugu states.\",\n      \"url\": \"https://indianexpress.com/article/entertainment/regional/kgf-chapter-2-box-office-day-1-yash-starrer-creates-history-7870297/\",\n      \"urlToImage\": \"https://images.indianexpress.com/2022/04/kgf-box-office.jpg\",\n      \"publishedAt\": \"2022-04-15T15:09:24Z\",\n      \"content\": \"Kannada movie KGF: Chapter 2, starring Yash in the lead role, has stormed the Indian box office. Thanks to the huge demand created by the film’s first part in 2018, the sequel reaped the benefit by o… [+2922 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"PINKVILLA\"\n      },\n      \"author\": \"Pinkvilla Desk\",\n      \"title\": \"Ranbir Kapoor-Alia Bhatt Wedding: Actress skipped chooda ceremony due to her Hollywood debut; Reports - PINKVILLA\",\n      \"description\": \"Alia Bhatt reportedly didn2019t do the traditional chooda ceremony due to her big Hollywood debut with Gal Gadot.\",\n      \"url\": \"https://www.pinkvilla.com/entertainment/news/ranbir-kapoor-alia-bhatt-wedding-actress-skipped-chooda-ceremony-due-her-hollywood-debut-reports-1068918\",\n      \"urlToImage\": \"https://www.pinkvilla.com/files/styles/fbimagesection/public/ranbir_alia_social_0.jpg?itok=RiRlyEBC\",\n      \"publishedAt\": \"2022-04-15T14:21:48Z\",\n      \"content\": \"Tinsel town's favourite couple, Alia Bhatt and Ranbir Kapoor got married on April 14th at the Yeh Jawaani Hai Deewani actor's Vastu residence in Bandra, Mumbai after dating for five years. The couple… [+1423 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NDTV News\"\n      },\n      \"author\": null,\n      \"title\": \"India Receives S-400 Overhauled Engines, Spares From Russia: Report - NDTV\",\n      \"description\": \"Amid the ongoing war between Russia and Ukraine, India has received the simulators and other equipment from Moscow for the training squadron of the S-400 Triumf air defence missile system.\",\n      \"url\": \"https://www.ndtv.com/india-news/india-russia-s-400-deal-india-russia-defence-deal-russia-ukraine-war-india-recieves-s-400-overhauled-engines-spares-from-russia-report-2891267\",\n      \"urlToImage\": \"https://i.ndtvimg.com/i/2016-10/s-400-missiles-reuters_650x400_51476365973.jpg\",\n      \"publishedAt\": \"2022-04-15T13:02:56Z\",\n      \"content\": \"India-Russia S-400 Missile System: The supplies from Russia included overhauled fighter engines.\\r\\nNew Delhi: Amid the ongoing war between Russia and Ukraine, India has received the simulators and oth… [+2188 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Livemint\"\n      },\n      \"author\": \"Livemint\",\n      \"title\": \"Tata Sons Effects Major Reshuffle In Air India's Top Management | Mint - Mint\",\n      \"description\": \"Aggarwal, who is also Senior Vice President at Tata Sons, replaces Air India veteran Meenakshi Malik, while Tripathi, who was Vice President of Human Resources at Tata Steel from 2012 to 2021, succeeds AI's Amrita Sharan.\",\n      \"url\": \"https://www.livemint.com/companies/news/tata-sons-effects-major-reshuffle-in-air-india-s-top-management-11650026050123.html\",\n      \"urlToImage\": \"https://images.livemint.com/img/2022/04/15/600x338/Air_India_1650026093350_1650026093656.jpg\",\n      \"publishedAt\": \"2022-04-15T12:36:06Z\",\n      \"content\": \"Tata Sons has effected a major reshuffle in the top management of Air India, news agency PTI reported on Friday.\\r\\nThe group chairman N Chandrasekaran issued the order, according to which, Air India v… [+1836 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"the-times-of-india\",\n        \"name\": \"The Times of India\"\n      },\n      \"author\": \"Aishwarya Dharni\",\n      \"title\": \"Indian-Origin NASA Astronaut Raja Chari All Set To Return To Earth After Six Months In Space - Indiatimes.com\",\n      \"description\": \"After spending six months in microgravity, astronaut Raja Chari is all set to return home. The Crew-3 astronauts who docked to the International Space Station in November last year will return to planet Earth later this month. NASA astronauts Raja Chari, Tom …\",\n      \"url\": \"https://www.indiatimes.com/trending/social-relevance/indian-american-astronaut-raja-chari-to-return-home-567090.html\",\n      \"urlToImage\": \"https://im.indiatimes.in/content/2022/Apr/raja-chari_6259659bac146.png\",\n      \"publishedAt\": \"2022-04-15T12:25:40Z\",\n      \"content\": \"After spending six months in microgravity, astronaut Raja Chari is all set to return home. The Crew-3 astronauts who docked to the International Space Station in November last year will return to pla… [+2049 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Livemint\"\n      },\n      \"author\": \"Pooja Sitaram Jaiswar\",\n      \"title\": \"Rakesh Jhunjhunwala Raises Stake In This Infra Stock During Q4 | Mint - Mint\",\n      \"description\": \"The latest shareholding data of NCC on exchanges showed that Rekha Jhunjhunwala's holding in the company now stands at 1.6 crore equity shares or 2.62% as of March 2022.\",\n      \"url\": \"https://www.livemint.com/market/stock-market-news/rakesh-jhunjhunwala-raises-stake-in-this-infra-stock-during-q4-11650024996162.html\",\n      \"urlToImage\": \"https://images.livemint.com/img/2022/04/15/600x338/5244bf12-7a11-11ec-9eea-9c1e2652c262_1644643836353_1650025079879.jpg\",\n      \"publishedAt\": \"2022-04-15T12:22:15Z\",\n      \"content\": \"Ace investor Rakesh Jhunjhunwala has increased shareholding in the construction and engineering company, NCC Limited, through his wife's portfolio Rekha Jhunjhunwala. The investor who is referred to … [+3686 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NDTV News\"\n      },\n      \"author\": null,\n      \"title\": \"Russia Pledges More Missile Attacks On Kyiv After Moskva Flagship Sinks - NDTV\",\n      \"description\": \"Moscow warned Friday it would step up missile attacks on Kyiv in response to what it said were sorties across the border, the day after its Black Sea naval flagship sank.\",\n      \"url\": \"https://www.ndtv.com/world-news/russia-ukraine-war-kyiv-missile-attacks-russia-pledges-more-missile-attacks-on-kyiv-after-moskva-flagship-sinks-2890987\",\n      \"urlToImage\": \"https://c.ndtvimg.com/2022-03/2171rpvg_shelling-podil-districtkyivreuters-_625x300_21_March_22.jpg\",\n      \"publishedAt\": \"2022-04-15T11:33:21Z\",\n      \"content\": \"Russia-Ukraine War: Russia attacked a factory near Kyiv where Neptune missiles were manufactured. (File)\\r\\nKyiv: Moscow warned Friday it would step up missile attacks on Kyiv in response to what it sa… [+5437 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"the-times-of-india\",\n        \"name\": \"The Times of India\"\n      },\n      \"author\": \"PTI\",\n      \"title\": \"If harmed, India will not spare anyone, says Rajnath Singh in a strong message to China - Economic Times\",\n      \"description\": \"Singh, in his address to the Indian-American community in San Francisco, also sent a subtle message to the US that New Delhi does not believe in a diplomacy of  zero-sum game  and its relationship with one country cannot be at the expense of the other.\",\n      \"url\": \"https://economictimes.indiatimes.com/news/defence/if-harmed-india-will-not-spare-anyone-says-rajnath-singh-in-a-strong-message-to-china/articleshow/90863870.cms\",\n      \"urlToImage\": \"https://img.etimg.com/thumb/msid-90863903,width-1070,height-580,imgsize-27366,overlay-etdefence/photo.jpg\",\n      \"publishedAt\": \"2022-04-15T11:32:00Z\",\n      \"content\": \"In a strong message to China, Defence Minister Rajnath Singh has said that if harmed, India will not spare anyone, as he asserted that India under Prime Minister Narendra Modi has emerged as a powerf… [+5028 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"India Today\"\n      },\n      \"author\": null,\n      \"title\": \"Closing schools would be last option, says Manish Sisodia amid rising Covid cases in Delhi - India Today\",\n      \"description\": \"The Delhi Directorate of Education issued an advisory for students on Friday, following reports of rising Covid cases. \\\"Partial closure of schools would be implemented if required,\\\" said deputy CM Manish Sisodia.\",\n      \"url\": \"https://www.indiatoday.in/coronavirus-outbreak/story/closing-schools-would-be-last-option-says-manish-sisodia-amid-reports-of-rising-covid-cases-in-delhi-1937939-2022-04-15\",\n      \"urlToImage\": \"https://akm-img-a-in.tosshub.com/indiatoday/images/story/202204/Delhi_students_Covid_PTI-647x363.jpeg?gAOfpQ3bwoIzw92GXQJmhvLSnALaSyXL\",\n      \"publishedAt\": \"2022-04-15T11:18:31Z\",\n      \"content\": \"As Covid cases are again on the rise, the Delhi Directorate of Education issued guidelines for students on Friday. \\\"Closing schools would be the last option. Partial closure would be implemented if r… [+1557 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Iplt20.com\"\n      },\n      \"author\": null,\n      \"title\": \"Deepak Chahar ruled out of TATA IPL 2022, Harshit Rana joins KKR as a replacement for Rasikh Salam - IPLT20.com\",\n      \"description\": \"Deepak Chahar ruled out of TATA IPL 2022, Harshit Rana joins KKR as a replacement for Rasikh Salam\",\n      \"url\": \"https://www.iplt20.com/news/3764/deepak-chahar-ruled-out-of-tata-ipl-2022-harshit-rana-joins-kkr-as-a-replacement-for-rasikh-salam\",\n      \"urlToImage\": \"https://assets.iplt20.com/bcci/articles/1650020545_aa.jpeg\",\n      \"publishedAt\": \"2022-04-15T11:08:49Z\",\n      \"content\": null\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Pragativadi.com\"\n      },\n      \"author\": \"Pradeep Sahoo\",\n      \"title\": \"iQOO Z6 Pro 5G India Launch Set To April 27; Snapdragon 778G 5G Chip & 66W Fast Charging Confirmed - Pragativadi\",\n      \"description\": \"New Delhi: iQoo Z6 Pro 5G India launch date has been set for April 27 as the Chinese smartphone manufacturer announced. The handset will also feature the company’s VC liquid cooling technology and is claimed to offer the highest AnTuTu benchmark scor\",\n      \"url\": \"https://pragativadi.com/iqoo-z6-pro-5g-india-launch-set-to-april-27-snapdragon-778g-5g-chip-66w-fast-charging-confirmed/\",\n      \"urlToImage\": \"https://pragativadi.com/wp-content/uploads/2022/04/aaa.jpg\",\n      \"publishedAt\": \"2022-04-15T11:04:21Z\",\n      \"content\": \"New Delhi: iQoo Z6 Pro 5G India launch date has been set for April 27 as the Chinese smartphone manufacturer announced. The handset will also feature the companys VC liquid cooling technology and is … [+1414 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"the-times-of-india\",\n        \"name\": \"The Times of India\"\n      },\n      \"author\": \"TIMESOFINDIA.COM\",\n      \"title\": \"Twitter shareholder Saudi Prince rejects Elon Musk's offer; Tesla chief reacts - Times of India\",\n      \"description\": \"International Business News: NEW DELHI: Saudi Prince Alwaleed bin Talal, who owns a major stake in social media platform Twitter, rejected Elon Musk's offer to acquire 100 per cen.\",\n      \"url\": \"https://timesofindia.indiatimes.com/business/international-business/twitter-shareholder-saudi-prince-rejects-elon-musks-offer-tesla-chief-reacts/articleshow/90862756.cms\",\n      \"urlToImage\": \"https://static.toiimg.com/thumb/msid-90862992,width-1070,height-580,imgsize-24050,resizemode-75,overlay-toi_sw,pt-32,y_pad-40/photo.jpg\",\n      \"publishedAt\": \"2022-04-15T10:39:00Z\",\n      \"content\": \"I don't believe that the proposed offer by @elonmusk ($54.20) comes close to the intrinsic value of @Twitter given https://t.co/PImKaphxuS\\r\\n— (@Alwaleed_Talal) 1649947559000\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"India.com\"\n      },\n      \"author\": \"India.com Lifestyle Staff\",\n      \"title\": \"7 Reasons Why You are Gaining Belly Fat and Tips to Reduce it - India.com\",\n      \"description\": \"Make some changes to your lifestyle to help reverse the scale and feel better.\",\n      \"url\": \"https://www.india.com/health/weight-loss-tips-7-reasons-why-you-gaining-belly-fat-and-tips-to-reduce-it-5339525/\",\n      \"urlToImage\": \"https://static.india.com/wp-content/uploads/2022/04/pexels-andres-ayrton-6551059.jpg\",\n      \"publishedAt\": \"2022-04-15T10:19:53Z\",\n      \"content\": \"Has your waistline expanded since the pandemic began? Don’t worry, you are not alone. A lifestyle that confines you inside the four walls of a house, with limited movement, is bound to add inches to … [+4334 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Hindustan Times\"\n      },\n      \"author\": \"HT Tech\",\n      \"title\": \"Top 5 Windows 11 features: If you are not using them, you’re missing out - HT Tech\",\n      \"description\": \"Top 5 Windows 11 features: Windows 11 brought a wide range of changes and new additions, but these are arguably the best of them. Have you checked all of these out?\",\n      \"url\": \"https://tech.hindustantimes.com/tech/news/top-5-windows-11-features-if-you-are-not-using-them-you-re-missing-out-71650017645967.html\",\n      \"urlToImage\": \"https://images.hindustantimes.com/tech/img/2022/04/15/1600x900/Windows_11_(7)_1633403699297_1650017692498.jpg\",\n      \"publishedAt\": \"2022-04-15T10:17:13Z\",\n      \"content\": \"Top 5 Windows 11 features: Microsoft started rolling out Windows 11 starting October 2021 and promised a completely redesigned user-interface, new productivity tools and cool features that create a s… [+2581 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"News18\"\n      },\n      \"author\": \"Buzz Staff\",\n      \"title\": \"'Alien Footprints': NASA Image of Martian Crater is a Treat for Astronomy Nerds - News18\",\n      \"description\": \"NASA has released a new image of a crater on Mars.\",\n      \"url\": \"https://www.news18.com/news/buzz/alien-footprints-nasa-image-of-martian-crater-is-a-treat-for-astronomy-nerds-4988995.html\",\n      \"urlToImage\": \"https://images.news18.com/ibnlive/uploads/2022/04/martian-crater--165001301416x9.jpg\",\n      \"publishedAt\": \"2022-04-15T09:14:40Z\",\n      \"content\": \"NASA recently shared an image on its Instagram handle leaving the netizens completely stunned. The space agency has released a new image of a Mars crater. In the caption, NASA wrote, “Youre looking a… [+2101 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Indian Express\"\n      },\n      \"author\": \"Sports Desk\",\n      \"title\": \"Joe Root steps down as England’s Test team captain - The Indian Express\",\n      \"description\": \"Root was appointed as Sir Alastair Cook's successor in 2017, and holds the record for the most number of matches and wins as England Test captain.\",\n      \"url\": \"https://indianexpress.com/article/sports/cricket/joe-root-resigns-as-englands-test-team-captain-7870558/\",\n      \"urlToImage\": \"https://images.indianexpress.com/2022/03/joe-root.jpg\",\n      \"publishedAt\": \"2022-04-15T08:28:50Z\",\n      \"content\": \"Joe Root has stepped down as England Test captain following a run of poor results capped by dispiriting tours of Australia and the Caribbean.The 31-year-old was appointed as Alastair Cook’s successor… [+3209 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Indian Express\"\n      },\n      \"author\": \"Shubhra Gupta\",\n      \"title\": \"Mai review: Sakshi Tanwar shines in Netflix series - The Indian Express\",\n      \"description\": \"Mai review: Despite the elements that stretch our credulity, Sakshi Tanwar manages to hold our attention.\",\n      \"url\": \"https://indianexpress.com/article/entertainment/web-series/mai-review-sakshi-tanwar-raima-sen-7870464/\",\n      \"urlToImage\": \"https://images.indianexpress.com/2022/04/Mai-review-120.jpg\",\n      \"publishedAt\": \"2022-04-15T07:48:09Z\",\n      \"content\": \"Mai cast: Sakshi Tanwar, Vivek Mushran, Wamiqa Gabbi, Raima Sen, Prashant Narayanan, Ankur Ratan, Anant Vidhaat, Vaibhav Raj Gupta, Seema PahwaMai directors: Anshai Lal, Atul MongiaMai pulls off a to… [+4294 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NDTV News\"\n      },\n      \"author\": null,\n      \"title\": \"Moon Dust Collected By Neil Armstrong During Apollo 11 Mission Sells For $500,000 At Auction - NDTV\",\n      \"description\": \"A minuscule amount of lunar dust collected by Neil Armstrong during Apollo 11, the mission that first put men on the Moon, has been sold for $504,375 at an auction on Wednesday.\",\n      \"url\": \"https://www.ndtv.com/world-news/moon-dust-collected-by-neil-armstrong-during-apollo-11-mission-sells-for-500-000-at-auction-2890273\",\n      \"urlToImage\": \"https://c.ndtvimg.com/2022-04/sa75jpj_moon-650_625x300_15_April_22.jpg\",\n      \"publishedAt\": \"2022-04-15T06:54:03Z\",\n      \"content\": \"NASA even went to court to fight for the ownership of the lunar dust.\\r\\nA minuscule amount of lunar dust collected by Neil Armstrong during the Apollo 11 mission, that first put men on the Moon, has b… [+2060 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"ESPN India\"\n      },\n      \"author\": \"Sam Marsden\",\n      \"title\": \"Furious Barcelona seek answers after 20,000 Frankfurt fans flood Camp Nou - ESPN India\",\n      \"description\": \"Barcelona's coach and players want to know how at least 20,000 Eintracht Frankfurt fans gained access to the home end at Camp Nou.\",\n      \"url\": \"https://www.espn.in/football/story/4642402/furious-barcelona-seek-answers-after-20,000-frankfurt-fans-flood-camp-nou\",\n      \"urlToImage\": \"https://a3.espncdn.com/combiner/i?img=%2Fphoto%2F2022%2F0414%2Fr999905_1296x729_16%2D9.jpg\",\n      \"publishedAt\": \"2022-04-15T06:45:36Z\",\n      \"content\": \"Barcelona coach Xavi Hernandez says his players want to know how at least 20,000 Eintracht Frankfurt fans gained access to the home end at Camp Nou on Thursday as his side were knocked out of the Eur… [+3569 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Indian Express\"\n      },\n      \"author\": \"Express News Service\",\n      \"title\": \"Delhi: Cops remove saffron flags, banners put up by Hindu Sena near JNU campus - The Indian Express\",\n      \"description\": \"Reacting to the police action, national president of Hindu Sena Vishnu Gupta said that by removing the flags, the police have disrespected the Constitution.\",\n      \"url\": \"https://indianexpress.com/article/delhi/delhi-cops-remove-saffron-flags-banners-put-up-by-hindu-sena-near-jnu-campus-7870385/\",\n      \"urlToImage\": \"https://images.indianexpress.com/2022/04/IMG-20220415-WA0017.jpg\",\n      \"publishedAt\": \"2022-04-15T06:23:54Z\",\n      \"content\": \"In protest against the violence that broke out at the Jawaharlal Nehru University (JNU) between two groups of students on Ram Navami, members of the Hindu Sena put up saffron flags and banners readin… [+2160 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"the-times-of-india\",\n        \"name\": \"The Times of India\"\n      },\n      \"author\": \"PTI\",\n      \"title\": \"Egypt approves India as wheat supplier: Piyush Goyal - Economic Times\",\n      \"description\": \"“Indian farmers are feeding the world. Egypt approves India as a wheat supplier. Modi Govt. steps in as the world looks for reliable alternate sources for steady food supply. Our farmers have ensured our granaries overflow and we are ready to serve the world,…\",\n      \"url\": \"https://economictimes.indiatimes.com/news/economy/foreign-trade/egypt-approves-india-as-wheat-supplier-piyush-goyal/articleshow/90858683.cms\",\n      \"urlToImage\": \"https://img.etimg.com/thumb/msid-90858680,width-1070,height-580,imgsize-2041580,overlay-economictimes/photo.jpg\",\n      \"publishedAt\": \"2022-04-15T05:21:00Z\",\n      \"content\": \"Commerce and Industry Minister Piyush Goyal on Friday said Egypt, which is one of the largest importers of wheat from Ukraine and Russia, has approved India as a wheat supplier.\\r\\nThere is a sharp dec… [+2046 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NDTV News\"\n      },\n      \"author\": null,\n      \"title\": \"China Hesitates On Bailing Out \\\"Sinking Ships\\\" Sri Lanka, Pakistan - NDTV\",\n      \"description\": \"Over the past few years, the U.S. has accused China of using \\\"debt diplomacy\\\" to make developing nations across the world more dependent on Beijing.\",\n      \"url\": \"https://www.ndtv.com/world-news/china-hesitates-on-bailing-out-sinking-ships-sri-lanka-pakistan-2887151\",\n      \"urlToImage\": \"https://c.ndtvimg.com/2022-04/ui5tc3fg_sri-lanka-protestsbloomberg-_625x300_14_April_22.jpg\",\n      \"publishedAt\": \"2022-04-15T04:23:00Z\",\n      \"content\": \"Sri Lanka President Gotabaya Rajapaksa is facing pressure from protesters to step down.\\r\\nOver the past few years, the U.S. has accused China of using \\\"debt diplomacy\\\" to make developing nations acros… [+6157 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Indian Express\"\n      },\n      \"author\": \"Lifestyle Desk\",\n      \"title\": \"Good Friday 2022: Inspirational Quotes, Images, and Messages of Jesus Christ - The Indian Express\",\n      \"description\": \"Good Friday 2022 Images, Quotes, Messages, Status, Jesus Christ Inspirational Quotes: It is held after the Christian holy day of Maundy Thursday, which commemorates the Last Supper of Jesus Christ, and on a Friday before Easter Sunday.\",\n      \"url\": \"https://indianexpress.com/article/lifestyle/life-style/good-friday-2022-inspirational-quotes-images-and-messages-of-jesus-christ-7867753/\",\n      \"urlToImage\": \"https://images.indianexpress.com/2022/04/good-friday-1200-1.jpg\",\n      \"publishedAt\": \"2022-04-15T04:00:36Z\",\n      \"content\": \"Good Friday 2022 Quotes: Good Friday, a Christian holy day, is observed the Friday before Easter Sunday to commemorate Jesus’ crucifixion. Christians believe that He sacrificed Himself to purge the w… [+1638 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Moneycontrol\"\n      },\n      \"author\": \"Nikhil Walavalkar\",\n      \"title\": \"82 percent of large-cap schemes underperform benchmarks over 5 years: SPIVA report - Moneycontrol\",\n      \"description\": \"The numbers for 2021 look better than the scorecard for 2020. The study showed 50 percent of the large cap equity funds underperformed the S&amp;P BSE 100 index in 2021 compared with 80 percent in 2020.\",\n      \"url\": \"https://www.moneycontrol.com/news/business/personal-finance/82-percent-of-large-cap-schemes-underperform-benchmarks-over-5-years-spiva-report-8361441.html\",\n      \"urlToImage\": \"https://images.moneycontrol.com/static-mcnews/2022/03/MUTUAL-FUNDS-770x431.png\",\n      \"publishedAt\": \"2022-04-15T02:44:47Z\",\n      \"content\": \"Its getting tougher for actively managed equity funds to outperform their benchmark indices. Many actively managed equity mutual fund schemes have underperformed the indices, according to the S&amp;P… [+4140 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"ThePrint\"\n      },\n      \"author\": null,\n      \"title\": \"‘Immersive’ look at 1998 Pokhran test, Emergency — new museum shows highs & lows of 13 past PMs - ThePrint\",\n      \"description\": \"PM Modi inaugurated Rs 271 crore the Pradhan Mantri Sangrahalaya — Museum of Prime Ministers — Thursday. Exhibits range from civil nuclear agreement and Pokhran, to Bofors and Emergency.\",\n      \"url\": \"https://theprint.in/india/immersive-look-at-1998-pokhran-test-emergency-new-museum-shows-highs-lows-of-13-past-pms/916716/\",\n      \"urlToImage\": \"https://static.theprint.in/wp-content/uploads/2022/04/museum-1.jpg\",\n      \"publishedAt\": \"2022-04-15T02:09:03Z\",\n      \"content\": \"New Delhi: The new Rs 271 crore Pradhan Mantri Sangrahalaya (Museum of Prime Ministers), inaugurated by Prime Minister Narendra Modi Thursday, highlights the achievements as well as the controversies… [+4910 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Hindustan Times\"\n      },\n      \"author\": \"HT Entertainment Desk\",\n      \"title\": \"Lock Upp: Poonam Pandey says her family was thrown out of a residential society - Hindustan Times\",\n      \"description\": \"Lock Upp day 46 written update: Poonam Pandey recalled one of her tough times on the show. On the other hand, Payal Rohatgi fought with Saisha Shinde while Mandana Karimi got into a fight with Anjali Arora. | Web Series\",\n      \"url\": \"https://www.hindustantimes.com/entertainment/web-series/lock-upp-day-46-written-update-poonam-pandey-recalls-the-time-her-family-was-thrown-out-of-a-residential-society-101649981922710.html\",\n      \"urlToImage\": \"https://images.hindustantimes.com/img/2022/04/15/1600x900/poonam_Pandey_crying_1649984064242_1649984064498.JPG\",\n      \"publishedAt\": \"2022-04-15T01:16:50Z\",\n      \"content\": \"On Thursday's episode of the ongoing reality show Lock Upp, Poonam Pandey was seen crying as she recalled the time when she could not get a house for herself, after stepping out of a hospital. Poonam… [+1906 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Thewire.in\"\n      },\n      \"author\": null,\n      \"title\": \"With Small Uptick in Cases, Should India Be Worried About a Fourth COVID Wave? - The Wire\",\n      \"description\": \"Health researcher Anurag Agrawal says with almost everybody having been infected once and a large chunk vaccinated, the country should not be too concerned about the recent rise in cases.\",\n      \"url\": \"https://thewire.in/health/with-small-uptick-in-cases-should-india-be-worried-about-a-fourth-covid-wave\",\n      \"urlToImage\": \"https://cdn.thewire.in/wp-content/uploads/2022/04/14182312/2022_4img10_Apr_2022_PTI04_10_2022_000191B-800x400.jpg\",\n      \"publishedAt\": \"2022-04-14T13:10:45Z\",\n      \"content\": \"This article was originally published on The Wire Science, our website dedicated to science, health and environment reportage and analysis. Follow, read and share.\\r\\nNew Delhi: There is currently a sm… [+8054 chars]\"\n    }, {\n      \"source\": {\n        \"id\": \"cnn\",\n        \"name\": \"CNN\"\n      },\n      \"author\": \"By <a href=\\\"/profiles/travis-caldwell\\\">Travis Caldwell</a>, <a href=\\\"/profiles/helen-regan\\\">Helen Regan</a>, Sana Noor Haq, Jack Bantock, <a href=\\\"/profiles/laura-smith-spark\\\">Laura Smith-Spark</a>, <a href=\\\"/profiles/adrienne-vogt\\\">Adrienne Vogt</a> and Melissa Macaya, CNN\",\n      \"title\": \"Russia invades Ukraine: Live updates - CNN\",\n      \"description\": \"Russian preparations continue in the east for an offensive operation, training additional units and gathering aviation forces, according to Ukraine's armed forces. Follow here for live news updates.\",\n      \"url\": \"https://www.cnn.com/europe/live-news/ukraine-russia-putin-news-04-15-22/index.html\",\n      \"urlToImage\": \"https://cdn.cnn.com/cnnnext/dam/assets/220414001151-mariupol-ukraine-burned-building-rivers-0412-super-tease.jpg\",\n      \"publishedAt\": \"2022-04-15T16:13:00Z\",\n      \"content\": \"Ukrainian President Volodymyr Zelensky told CNN Friday that \\\"all of the countries of the world\\\" should be prepared for the possibility that Russian President Vladimir Putin could use tactical nuclear… [+2268 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"the-washington-post\",\n        \"name\": \"The Washington Post\"\n      },\n      \"author\": \"Steven Zeitchik\",\n      \"title\": \"A Ukrainian refugee highlights the hope and heartbreak this Passover season - The Washington Post\",\n      \"description\": \"Dr. Jacob Gaissinovitch and his family first fled their home in Donetsk in 2014 when war arrived. Now they've fled Dnipro.\",\n      \"url\": \"https://www.washingtonpost.com/world/2022/04/15/ukraine-mohel-circumcision-refugee/\",\n      \"urlToImage\": \"https://www.washingtonpost.com/wp-apps/imrs.php?src=https://arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/RM7Z2R7JTBDJ7HAYHHVPAJAEQ4.jpg&w=1440\",\n      \"publishedAt\": \"2022-04-15T16:00:59Z\",\n      \"content\": \"Placeholder while article actions load\\r\\nHe has circumcised males aged eight days to 80 years. He has taken out his kit in synagogues and hospitals, made nervous mothers feel calm and geriatric men fe… [+12501 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"The Guardian\"\n      },\n      \"author\": \"Nina Lakhani\",\n      \"title\": \"‘That was my beloved son’: family of Patrick Lyoya say police killed their son in an ‘execution’ - The Guardian\",\n      \"description\": \"The family’s lawyer says Grand Rapid police officer broke protocol by using the Taser too close to Lyoya\",\n      \"url\": \"https://amp.theguardian.com/us-news/2022/apr/15/patrick-lyoya-shooting-family-police-killed-execution\",\n      \"urlToImage\": null,\n      \"publishedAt\": \"2022-04-15T15:08:00Z\",\n      \"content\": \"US policingThe familys lawyer says Grand Rapid police officer broke protocol by using the Taser too close to Lyoya\\r\\nFri 15 Apr 2022 16.08 BST\\r\\nThe grief-stricken parents of the Black man shot in the … [+5391 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Gizmodo.com\"\n      },\n      \"author\": \"Phillip Tracy\",\n      \"title\": \"M2 Macs Are Coming to Make Your Brand New Laptop Obsolete - Gizmodo\",\n      \"description\": \"Developer logs point to 9 M2 Mac models that are currently in testing.\",\n      \"url\": \"https://gizmodo.com/m2-macbook-air-macbook-pro-mac-mini-coming-1848798141\",\n      \"urlToImage\": \"https://i.kinja-img.com/gawker-media/image/upload/c_fill,f_auto,fl_progressive,g_center,h_675,pg_1,q_80,w_1200/82e18730953f1c53b02dc5864716636a.jpg\",\n      \"publishedAt\": \"2022-04-15T14:31:44Z\",\n      \"content\": \"Apple is readying its next fleet of laptops and desktops as it transitions into the second phase of Mac products powered by custom silicon, a new report from Bloomberg says.\\r\\nThe company is reportedl… [+3448 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"the-wall-street-journal\",\n        \"name\": \"The Wall Street Journal\"\n      },\n      \"author\": \"Andrew Restuccia, Andrew Duehren\",\n      \"title\": \"Biden to Nominate Michael Barr as Top Fed Banking Regulator - The Wall Street Journal\",\n      \"description\": \"If confirmed, former Obama Treasury official would oversee the largest U.S. financial firms\",\n      \"url\": \"https://www.wsj.com/articles/biden-to-nominate-michael-barr-as-top-fed-banking-regulator-11650013201\",\n      \"urlToImage\": \"https://images.wsj.net/im-524842/social\",\n      \"publishedAt\": \"2022-04-15T14:26:00Z\",\n      \"content\": \"WASHINGTONPresident Biden will nominate Michael Barr, a former Treasury Department official, to serve as the Federal Reserves top banking regulator, the White House said, after Mr. Bidens first pick … [+295 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"associated-press\",\n        \"name\": \"Associated Press\"\n      },\n      \"author\": \"Tom Krisher\",\n      \"title\": \"Modest-income buyers being priced out of new-vehicle market - The Associated Press\",\n      \"description\": \"DETROIT (AP) — Two years after the pandemic tore through the economy, America’s auto market looks something like this: Prices are drastically up. Supply is drastically down. And gasoline costs drastically more.\",\n      \"url\": \"https://apnews.com/7a001990f2d63bf6b3fa0188e37feb12\",\n      \"urlToImage\": \"https://storage.googleapis.com/afs-prod/media/9c9b5edf18e44fc18bbcbcf5061a2a5c/3000.jpeg\",\n      \"publishedAt\": \"2022-04-15T14:17:50Z\",\n      \"content\": \"DETROIT (AP) Two years after the pandemic tore through the economy, Americas auto market looks something like this: Prices are drastically up. Supply is drastically down. And gasoline costs drastical… [+5512 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Salt Lake Tribune\"\n      },\n      \"author\": null,\n      \"title\": \"'Please tell me what I should be saying.' Text messages show Sen. Mike Lee assisting Trump efforts to overturn 2020 election - Salt Lake Tribune\",\n      \"description\": \"Newly released text messages between Sen. Mike Lee and former White House chief of staff Mark Meadows show Lee's involvement in the effort to overturn the 2020 election results. Lee apparently was aware of a scheme to have states send competing slates of elec…\",\n      \"url\": \"https://www.sltrib.com/news/politics/2022/04/15/please-tell-me-what-i/\",\n      \"urlToImage\": \"https://www.sltrib.com/resizer/magQ0P9avDhcS8oCswvTqe0CLf8=/1200x630/cloudfront-us-east-1.images.arcpublishing.com/sltrib/XMRYVL4Q6NFCDH36TY5AHDULVA.jpg\",\n      \"publishedAt\": \"2022-04-15T14:17:08Z\",\n      \"content\": \"Newly released text messages between Sen. Mike Lee and former White House chief of staff Mark Meadows show Lee was advising and assisting former President Donald Trumps efforts to overturn the result… [+8474 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"New York Times\"\n      },\n      \"author\": \"Patrick Kingsley, Raja Abdulrahim\",\n      \"title\": \"Jerusalem Calms Following Israeli-Palestinian Clashes: Latest News and Live Updates - The New York Times\",\n      \"description\": \"Violence broke out at the Aqsa Mosque compound, known to Jews as the Temple Mount, in the morning on the first day of a rare convergence of Ramadan, Easter and Passover.\",\n      \"url\": \"https://www.nytimes.com/live/2022/04/15/world/jerusalem-al-aqsa-mosque\",\n      \"urlToImage\": \"https://static01.nyt.com/images/2022/04/15/world/15jerusalem-briefing-promo02/merlin_205512273_76eafc23-06cc-4997-b821-3b61466d7222-facebookJumbo.jpg\",\n      \"publishedAt\": \"2022-04-15T14:13:37Z\",\n      \"content\": \"Palestinians and the Israeli police clashing at the Aqsa Mosque compound in Jerusalem on Friday.Credit...Mahmoud Illean/Associated Press\\r\\nJERUSALEM The midday Muslim prayers at one of Jerusalems holi… [+4188 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"NBCSports.com\"\n      },\n      \"author\": \"Michael David Smith\",\n      \"title\": \"Colts sign Stephon Gilmore - NBC Sports\",\n      \"description\": \"The top available free agent has found his next team.Veteran cornerback Stephon Gilmore is signing with the Colts.Gilmore was the No. 18 player on our list of the NFL’s Top 100 free agents, and the highest-ranked player who wasn’t already spoken for. (Tyrann …\",\n      \"url\": \"https://profootballtalk.nbcsports.com/2022/04/15/colts-sign-stephon-gilmore/\",\n      \"urlToImage\": \"https://profootballtalk.nbcsports.com/wp-content/uploads/sites/25/2022/04/GettyImages-1277236370-e1650031375609.jpg\",\n      \"publishedAt\": \"2022-04-15T14:03:00Z\",\n      \"content\": \"The top available free agent has found his next team.\\r\\nVeteran cornerback Stephon Gilmore is signing with the Colts.\\r\\nGilmore was the No. 18 player on our list of the NFLs Top 100 free agents, and th… [+629 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"reuters\",\n        \"name\": \"Reuters\"\n      },\n      \"author\": null,\n      \"title\": \"Ukrainians hang on at Mariupol steel plant - Reuters\",\n      \"description\": \"Explosions rumbled and smoke rose this week from a steel making district in besieged Mariupol where dwindling Ukrainian forces are holed up as Russia tries to take full control of its biggest city yet.\",\n      \"url\": \"https://www.reuters.com/world/europe/fortress-city-ukrainians-cling-steel-plant-mariupol-2022-04-15/\",\n      \"urlToImage\": \"https://www.reuters.com/resizer/rw9Il5SxtxE7Dovkg1WDcIaOCSM=/1200x628/smart/filters:quality(80)/cloudfront-us-east-2.images.arcpublishing.com/reuters/NGTFN2NGNRIEJGGLDLEY33B2IU.jpg\",\n      \"publishedAt\": \"2022-04-15T13:45:00Z\",\n      \"content\": \"April 15 (Reuters) - Explosions rumbled and smoke rose this week from a steel making district in besieged Mariupol where dwindling Ukrainian forces are holed up as Russia tries to take full control o… [+5199 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Behind the Steel Curtain\"\n      },\n      \"author\": \"Andrew_Wilbar\",\n      \"title\": \"2022 NFL Mock Draft 4.0: 4 rounds, 7 trades, and a new Steelers QB - Behind The Steel Curtain\",\n      \"description\": \"The Steelers grab a quarterback in round 1 of my latest four-round mock draft.\",\n      \"url\": \"https://www.behindthesteelcurtain.com/2022/4/15/23025815/2022-nfl-mock-draft-4-0-steelers-qb-malik-willis-logan-hall-tyquan-thornton-isaac-taylor-stuart-news\",\n      \"urlToImage\": \"https://cdn.vox-cdn.com/thumbor/juHNZDcBSsAh4ZgoQlSw5r1Vxno=/0x227:3163x1883/fit-in/1200x630/cdn.vox-cdn.com/uploads/chorus_asset/file/23391571/usa_today_17381077.jpg\",\n      \"publishedAt\": \"2022-04-15T13:30:00Z\",\n      \"content\": \"We are less than two weeks away from the 2022 NFL Draft, and the draft rumor mill is beginning to pick up the pace. After a blockbuster trade and several key free agent signings in the past two weeks… [+15704 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"cnn\",\n        \"name\": \"CNN\"\n      },\n      \"author\": \"Lisa Respers France, CNN\",\n      \"title\": \"Cardi B. and Offset reveal their son's name - CNN\",\n      \"description\": \"Rappers Cardi B. and Offset welcomed their son seven months ago and we now know his name.\",\n      \"url\": \"https://www.cnn.com/2022/04/15/entertainment/cardi-offset-son-name/index.html\",\n      \"urlToImage\": \"https://cdn.cnn.com/cnnnext/dam/assets/220215130428-cardi-b-super-tease.jpg\",\n      \"publishedAt\": \"2022-04-15T13:20:00Z\",\n      \"content\": null\n    },\n    {\n      \"source\": {\n        \"id\": \"cnn\",\n        \"name\": \"CNN\"\n      },\n      \"author\": \"Katherine Dillinger\",\n      \"title\": \"FDA authorizes first Covid-19 breath test - CNN\",\n      \"description\": \"The US Food and Drug Administration has granted emergency use authorization to the first Covid-19 test that spots chemical compounds associated with the coronavirus in breath, the agency said Thursday.\",\n      \"url\": \"https://www.cnn.com/2022/04/14/health/covid-breath-test/index.html\",\n      \"urlToImage\": \"https://media.cnn.com/api/v1/images/stellar/prod/220415085321-inspectir-pny-1000-covid-breathalyzer.jpg?c=16x9&q=w_800,c_fill\",\n      \"publishedAt\": \"2022-04-15T13:01:00Z\",\n      \"content\": \"The US Food and Drug Administration has granted emergency use authorization to the first Covid-19 test that spots chemical compounds associated with the coronavirus in breath, the agency said Thursda… [+1084 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"New York Post\"\n      },\n      \"author\": \"Samantha Ibrahim\",\n      \"title\": \"Late Gilbert Gottfried left behind secret 'Aladdin' outtakes, 200 hours of footage - New York Post \",\n      \"description\": \"We haven’t seen the last of Gilbert Gottfried, who passed away earlier this month at the age of 67.\",\n      \"url\": \"https://nypost.com/2022/04/15/gilbert-gottfried-left-behind-secret-aladdin-outtakes-200-cameo-hours/\",\n      \"urlToImage\": \"https://nypost.com/wp-content/uploads/sites/2/2022/04/gottfried-parrot.jpg?quality=75&strip=all&w=1024\",\n      \"publishedAt\": \"2022-04-15T12:53:00Z\",\n      \"content\": \"We haven’t seen the last of Gilbert Gottfried.\\r\\nThere is apparently unseen footage featuring the comedian, who died on April 12 at the age of 67, in his role of the clever parrot Iago in Disney’s “Al… [+3528 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"fox-news\",\n        \"name\": \"Fox News\"\n      },\n      \"author\": \"Caitlin McFall\",\n      \"title\": \"Psaki: 'Not sending' Biden to Ukraine, 'we should all be maybe relieved about that' - Fox News\",\n      \"description\": \"White House press secretary Jen Psaki put a stop to questions about whether President Biden would travel to Ukraine Friday amid its ongoing war with Russia.\",\n      \"url\": \"https://www.foxnews.com/politics/psaki-not-sending-biden-to-ukraine\",\n      \"urlToImage\": \"https://static.foxnews.com/foxnews.com/content/uploads/2022/03/BIDEN-VISIT-POLAND-UKRAINE.jpg\",\n      \"publishedAt\": \"2022-04-15T12:51:32Z\",\n      \"content\": \"White House press secretary Jen Psaki put a stop to questions Friday about whether President Biden would travel to Ukraine amid its ongoing war with Russia.\\r\\n\\\"No. no,\\\" Psaki said in answer to questio… [+2564 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"ESPN\"\n      },\n      \"author\": \"Doug Glanville\",\n      \"title\": \"Why Jackie Robinson's story still resonates 75 years after his MLB debut - ESPN\",\n      \"description\": \"Every time No. 42's tale is told to a new generation, it keeps the lessons he taught us alive.\",\n      \"url\": \"https://www.espn.com/mlb/story/_/id/33729977/why-jackie-robinson-story-resonates-75-years-mlb-debut\",\n      \"urlToImage\": \"https://a3.espncdn.com/combiner/i?img=%2Fphoto%2F2022%2F0413%2Fr999249_1296x729_16%2D9.jpg\",\n      \"publishedAt\": \"2022-04-15T12:02:39Z\",\n      \"content\": \"FIVE YEARS AGO, during one of my eldest daughter's first Little League games of the season, I noticed her bouncing around at first base on each pitch. It was clear she was imitating someone, and give… [+10230 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"cnn\",\n        \"name\": \"CNN\"\n      },\n      \"author\": \"CNN\",\n      \"title\": \"READ: Mark Meadows' texts with Mike Lee and Chip Roy - CNN\",\n      \"description\": \"CNN has obtained text messages of separate conversations that then-White House chief of staff Mark Meadows had with Republican Sen. Mike Lee of Utah and Republican Rep. Chip Roy of Texas after the 2020 presidential election and through early January 2021.\",\n      \"url\": \"https://www.cnn.com/2022/04/15/politics/read-mark-meadows-texts-mike-lee-chip-roy/index.html\",\n      \"urlToImage\": \"https://cdn.cnn.com/cnnnext/dam/assets/220414181047-roy-meadows-lee-split-super-tease.jpg\",\n      \"publishedAt\": \"2022-04-15T11:06:00Z\",\n      \"content\": \"(CNN)CNN has obtained text messages of separate conversations that then-White House chief of staff Mark Meadows had with Republican Sen. Mike Lee of Utah and Republican Rep. Chip Roy of Texas after t… [+18257 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"ars-technica\",\n        \"name\": \"Ars Technica\"\n      },\n      \"author\": \"Ron Amadeo\",\n      \"title\": \"OnePlus 10 Pro review: There’s not much left of the original OnePlus appeal - Ars Technica\",\n      \"description\": \"Janky software and lacking updates mean there's too much compromise for $900.\",\n      \"url\": \"https://arstechnica.com/gadgets/2022/04/oneplus-10-pro-review-theres-not-much-left-of-the-original-oneplus-appeal/\",\n      \"urlToImage\": \"https://cdn.arstechnica.net/wp-content/uploads/2022/03/16-1-760x380.jpg\",\n      \"publishedAt\": \"2022-04-15T11:00:24Z\",\n      \"content\": \"Enlarge/ The OnePlus 10 Pro. It's a pretty normal smartphone for $900. \\r\\n24 with 20 posters participating\\r\\nOnePlus is in a period of upheaval.\\r\\nThe Chinese company lost its co-founder, Carl Pei, in 2… [+4437 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"the-wall-street-journal\",\n        \"name\": \"The Wall Street Journal\"\n      },\n      \"author\": \"Katherine Bindley\",\n      \"title\": \"California Considers the Four-Day Workweek - The Wall Street Journal\",\n      \"description\": \"Lawmakers propose 32 hours for private-sector companies with more than 500 employees\",\n      \"url\": \"https://www.wsj.com/articles/california-considers-the-four-day-workweek-11649994203\",\n      \"urlToImage\": \"https://images.wsj.net/im-523697/social\",\n      \"publishedAt\": \"2022-04-15T11:00:00Z\",\n      \"content\": \"Companies and governments around the world have been debating that question recently, driven by a tight labor market along with workers seeking more flexibility. A proposal in the California State Le… [+6090 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Electrek\"\n      },\n      \"author\": null,\n      \"title\": \"Elon Musk claims that ‘funding was secured’ in infamous Tesla ‘420 take private’ attempt, but SEC/banks forced him to settle - Electrek.co\",\n      \"description\": \"Elon Musk opened up in a new interview yesterday about the SEC lawsuit regarding his attempt to take Tesla private back in 2018 and his infamous “funding secured” announcement. The Tesla CEO now claims funding was indeed secured and that he was forced to sett…\",\n      \"url\": \"https://electrek.co/2022/04/15/elon-musk-claims-funding-was-secured-in-infamous-tesla-420-take-private-attempt-sec-banks-forced-settle/\",\n      \"urlToImage\": \"https://i0.wp.com/electrek.co/wp-content/uploads/sites/3/2020/09/VW-CEO-Hebert-Diess-Tesla-CEO-Elon-Musk-selfie-hero.jpg?resize=1200%2C628&quality=82&strip=all&ssl=1\",\n      \"publishedAt\": \"2022-04-15T10:48:00Z\",\n      \"content\": \"Elon Musk opened up in a new interview yesterday about the SEC lawsuit regarding his attempt to take Tesla private back in 2018 and his infamous “funding secured” announcement.\\r\\nThe Tesla CEO now cla… [+4861 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"YouTube\"\n      },\n      \"author\": null,\n      \"title\": \"Clashes in Shanghai, China, over Covid lockdown evictions – BBC News - BBC News\",\n      \"description\": \"Video has emerged of clashes between police and people being forced out of their homes in Shanghai, as the city enters a third week of Covid lockdown.Some re...\",\n      \"url\": \"https://www.youtube.com/watch?v=nSkSj9H_t9g\",\n      \"urlToImage\": \"https://i.ytimg.com/vi/nSkSj9H_t9g/hqdefault.jpg\",\n      \"publishedAt\": \"2022-04-15T10:33:43Z\",\n      \"content\": null\n    },\n    {\n      \"source\": {\n        \"id\": \"independent\",\n        \"name\": \"Independent\"\n      },\n      \"author\": \"Oliver O'Connell\",\n      \"title\": \"Johnny Depp trial - live: Witness ejected from court as Amber Heard called ‘scum’ in ex’s texts - The Independent\",\n      \"description\": \"Johnny Depp - Amber Heard trial\",\n      \"url\": \"https://www.independent.co.uk/news/world/americas/johnny-depp-trial-live-amber-heard-court-b2058640.html\",\n      \"urlToImage\": \"https://static.independent.co.uk/2022/04/11/10/newFile-8.jpg?quality=75&width=1200&auto=webp\",\n      \"publishedAt\": \"2022-04-15T09:45:00Z\",\n      \"content\": \"The trial for Johnny Depps defamation lawsuit against former wife, Amber Heard, has adjourned until Monday after a third day of testimony in Virginia.\\r\\nOn Thursday, witness Gina Deuters, a friend of … [+6957 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"axios\",\n        \"name\": \"Axios\"\n      },\n      \"author\": \"Dan Primack, Sara Fischer\",\n      \"title\": \"Billionaires eye parallel media universe - Axios\",\n      \"description\": \"Tech moguls willing to spend big on \\\"free speech\\\" crisis\",\n      \"url\": \"https://www.axios.com/elon-musk-twitter-billionaires-free-speech-social-media-c74547a6-e51d-48fa-b2bd-3d7458f2adb4.html\",\n      \"urlToImage\": \"https://images.axios.com/cMrBX7vqRny-xhMZ-Hnm9Febnl8=/0x0:1920x1080/1366x768/2022/04/14/1649968930603.jpg\",\n      \"publishedAt\": \"2022-04-15T09:03:09Z\",\n      \"content\": \"Elon Musk doesn't seem to have much of a vision for how to actually run Twitter, if his takeover bid succeeds. He's not alone.\\r\\nWhy it matters: A small group of tech moguls believe America is in the … [+4393 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"cnn\",\n        \"name\": \"CNN\"\n      },\n      \"author\": \"Radina Gigova, Sharon Braithwaite, Jorge Engels, Sarah Diab and Bethlehem Feleke, CNN\",\n      \"title\": \"UK announces controversial plan to send asylum-seekers to Rwanda - CNN\",\n      \"description\": \"People seeking asylum in the UK could now be relocated to Rwanda under a controversial new scheme blasted by international human rights groups as \\\"shockingly ill-conceived\\\" and contrary to international obligations.\",\n      \"url\": \"https://www.cnn.com/2022/04/14/europe/uk-rwanda-migrant-deal-gbr-intl/index.html\",\n      \"urlToImage\": \"https://cdn.cnn.com/cnnnext/dam/assets/220414165211-boris-johnson-illegal-migrants-041422-super-tease.jpg\",\n      \"publishedAt\": \"2022-04-15T08:32:00Z\",\n      \"content\": null\n    },\n    {\n      \"source\": {\n        \"id\": \"politico\",\n        \"name\": \"Politico\"\n      },\n      \"author\": null,\n      \"title\": \"Seeking: GOP dealmakers who won't 'burn the House down'. Apply to: Kevin McCarthy. - POLITICO\",\n      \"description\": \"The undisputed frontrunner for speaker next year is set to lose a half-dozen Republicans from his conference who prefer negotiating to obstinacy. That could be a problem.\",\n      \"url\": \"https://www.politico.com/news/2022/04/15/gop-dealmakers-house-kevin-mccarthy-00025261\",\n      \"urlToImage\": \"https://static.politico.com/8a/b4/189aacde4147a61b395017dbf3d6/https-delivery.gettyimages.com/downloads/1177076170\",\n      \"publishedAt\": \"2022-04-15T08:30:00Z\",\n      \"content\": \"We cant have this mindset of burn the House down, said Rep. Don Bacon of Nebraska, another Republican with a bipartisan streak who plans to stick around next year. We got to be a governing party when… [+5953 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Cbslocal.com\"\n      },\n      \"author\": \"WCCO-TV Staff\",\n      \"title\": \"Take Down Your Bird Feeders To Stop Spread Of Bird Flu, U Of M Raptor Center Says - CBS Minnesota\",\n      \"description\": \"To help mitigate the spread of bird flu, the Raptor Center at the University of Minnesota is asking people to take down bird feeders and stop using bird baths this spring.\",\n      \"url\": \"https://minnesota.cbslocal.com/2022/04/15/take-down-your-bird-feeders-to-stop-spread-of-bird-flu-u-of-m-raptor-center-says/\",\n      \"urlToImage\": \"https://minnesota.cbslocal.com/wp-content/uploads/sites/15909630/2022/04/GettyImages-1201463951.jpg?w=1500\",\n      \"publishedAt\": \"2022-04-15T07:41:00Z\",\n      \"content\": \"MINNEAPOLIS (WCCO) – To help mitigate the spread of bird flu, the Raptor Center at the University of Minnesota is asking people to take down bird feeders and stop using bird baths this spring.\\r\\n“Beca… [+1237 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Android Authority\"\n      },\n      \"author\": null,\n      \"title\": \"WhatsApp details upcoming communities feature and other big updates - Android Authority\",\n      \"description\": \"Communities are coming to WhatsApp and the chat app has detailed how they will work. Several other new features are also headed to the app.\",\n      \"url\": \"https://www.androidauthority.com/whatsapp-communities-new-features-3153950/\",\n      \"urlToImage\": \"https://www.androidauthority.com/wp-content/uploads/2020/02/WhatsApp-by-Facebook-stock-photo-3.jpg\",\n      \"publishedAt\": \"2022-04-15T04:21:26Z\",\n      \"content\": \"<ul><li>WhatsApp has detailed its new communities feature coming to the app.</li><li>The company has also announced a bunch of other features, including the ability to share larger files, emoji react… [+1557 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"New York Times\"\n      },\n      \"author\": \"Victor Mather\",\n      \"title\": \"The USFL Has Returned. What to Know as Games Kick Off. - The New York Times\",\n      \"description\": \"Here’s what to know about the pro football league with the familiar name that begins its season on Saturday.\",\n      \"url\": \"https://www.nytimes.com/2022/04/15/sports/football/usfl-faq.html\",\n      \"urlToImage\": \"https://static01.nyt.com/images/2022/04/14/sports/14usfl/14usfl-facebookJumbo.jpg\",\n      \"publishedAt\": \"2022-04-15T04:01:09Z\",\n      \"content\": \"Overtime games will be decided by a shootout style competition. Each team will get three shots at the end zone from the 2-yard line. Whichever team reaches pay dirt more will win.\\r\\nAs an alternative … [+1158 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"SciTechDaily\"\n      },\n      \"author\": null,\n      \"title\": \"Liquid Hydrogen Leak Ends NASA's Third Test Attempt at Fueling the Artemis I SLS Moon Rocket - SciTechDaily\",\n      \"description\": \"Teams concluded today’s wet dress rehearsal test at approximately 5:10 p.m. EDT after observing a liquid hydrogen (LH2) leak on the tail service mast umbilical, which is located at the base of the mobile launcher and connects to the rocket’s core stage. The l…\",\n      \"url\": \"https://scitechdaily.com/liquid-hydrogen-leak-ends-nasas-third-test-attempt-at-fueling-the-artemis-i-sls-moon-rocket/\",\n      \"urlToImage\": \"https://scitechdaily.com/images/Artemis-I-Wet-Dress-Rehearsal-Prelaunch-Test-scaled.jpg\",\n      \"publishedAt\": \"2022-04-15T02:39:03Z\",\n      \"content\": \"A sunrise view of the Artemis I Space Launch System (SLS) and Orion spacecraft at Launch Pad 39B at NASAs Kennedy Space Center in Florida on April 11, 2022. Mist rises from a nearby waterway. The SLS… [+1967 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Deadline\"\n      },\n      \"author\": \"Tom Tapp\",\n      \"title\": \"3 Times More Los Angeles Residents Infected With Covid Than Previously Reported, Says Study - Deadline\",\n      \"description\": \"A new state study suggests the number of people in Los Angeles County who have been infected with Covid-19 during the pandemic is far greater than the number confirmed through standard testing. That’s due largely to the number of people who never developed sy…\",\n      \"url\": \"https://deadline.com/2022/04/more-los-angeles-residents-infected-with-covid-1235002878/\",\n      \"urlToImage\": \"https://deadline.com/wp-content/uploads/2021/03/AdobeStock_90015597.jpeg?w=1024\",\n      \"publishedAt\": \"2022-04-15T02:36:00Z\",\n      \"content\": \"A new state study suggests the number of people in Los Angeles County who have been infected with Covid-19 during the pandemic is far greater than the number confirmed through standard testing. That’… [+3981 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"cnn\",\n        \"name\": \"CNN\"\n      },\n      \"author\": \"Max Foster and Amir Vera, CNN\",\n      \"title\": \"Harry and Meghan visit Queen Elizabeth II on way to Invictus Games - CNN\",\n      \"description\": \"A spokesperson for the Duke and Duchess of Sussex has confirmed to CNN that the couple visited Queen Elizabeth II on their way to The Hague to attend The Invictus Games, which begin on Saturday.\",\n      \"url\": \"https://www.cnn.com/2022/04/14/uk/harry-megan-visit-queen-gbr-uk-intl/index.html\",\n      \"urlToImage\": \"https://cdn.cnn.com/cnnnext/dam/assets/220414175725-prince-harry-meghan-markle-file-restricted-092321-super-tease.jpg\",\n      \"publishedAt\": \"2022-04-14T23:21:00Z\",\n      \"content\": \"(CNN)A spokesperson for the Duke and Duchess of Sussex has confirmed to CNN that the couple visited Queen Elizabeth II on their way to The Hague to attend The Invictus Games, which begin on Saturday.… [+1199 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"cbs-news\",\n        \"name\": \"CBS News\"\n      },\n      \"author\": \"Tori B. Powell\",\n      \"title\": \"How to tell the difference between seasonal allergies and COVID-19 - CBS News\",\n      \"description\": \"As allergy season collides with another rise in COVID-19 cases, deciphering between symptoms can be tricky.\",\n      \"url\": \"https://www.cbsnews.com/news/covid-19-seasonal-allergies-symptoms-difference/\",\n      \"urlToImage\": \"https://cbsnews1.cbsistatic.com/hub/i/r/2022/03/16/eb9a53c9-b935-4bb7-b7c4-6471c9d64e07/thumbnail/1200x630g4/ec28ad1672bc9fd50d7a3b1c9bd61ae3/gettyimages-1208832904.jpg\",\n      \"publishedAt\": \"2022-04-14T22:54:00Z\",\n      \"content\": \"As allergy season collides with yet another rise in COVID-19 cases nationwide, deciphering the difference between symptoms of the coronavirus and allergies can be tricky. So how can you tell the diff… [+2079 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"New York Times\"\n      },\n      \"author\": \"Robin George Andrews\",\n      \"title\": \"Hubble Telescope Zooms In on the Biggest Comet Ever Spotted - The New York Times\",\n      \"description\": \"The space observatory helped scientists make a more precise measurement of the comet, which has a mass of 500 trillion tons and an appearance like burned toast.\",\n      \"url\": \"https://www.nytimes.com/2022/04/14/science/biggest-comet-hubble.html\",\n      \"urlToImage\": \"https://static01.nyt.com/images/2022/04/14/science/14sci-comet1/14sci-comet1-facebookJumbo.jpg\",\n      \"publishedAt\": \"2022-04-14T20:20:31Z\",\n      \"content\": \"Last year, scientists announced that they had discovered a colossal comet lingering just inside Neptunes orbit. They estimated its icy core to be between 62 and 125 miles long, based on its brightnes… [+1182 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"Yahoo Entertainment\"\n      },\n      \"author\": \"Reuters\",\n      \"title\": \"Moldova says reports Russian army trying to recruit its citizens are dangerous - Yahoo News\",\n      \"description\": \"Moldova said on Wednesday that reports that Russia's army was trying to recruit Moldovan citizens were dangerous and that it was regularly discussing all...\",\n      \"url\": \"https://news.yahoo.com/moldova-accuses-russian-army-trying-123532157.html\",\n      \"urlToImage\": \"https://s.yimg.com/uu/api/res/1.2/uNvOeXl_7_h.SI4B01g2uQ--~B/aD01Njg7dz04MDA7YXBwaWQ9eXRhY2h5b24-/https://media.zenfs.com/en/reuters.com/707a738453c3a1e8561b6ee252c55a17\",\n      \"publishedAt\": \"2022-04-14T12:35:32Z\",\n      \"content\": \"CHISINAU (Reuters) - (This April 14 story makes clear in headline and first paragraph that Moldova did not directly accuse the Russian army, and corrects day on which minister made comments; in fourt… [+2431 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": null,\n        \"name\": \"San Francisco Chronicle\"\n      },\n      \"author\": \"Lauren Hernández\",\n      \"title\": \"California lifts five-day quarantine rule for people exposed to COVID-19 but show no symptoms - San Francisco Chronicle\",\n      \"description\": \"The updated quarantine guidance does not apply to people who live or work in high-risk...\",\n      \"url\": \"https://www.sfchronicle.com/bayarea/article/California-lifts-five-day-quarantine-rule-for-17079881.php\",\n      \"urlToImage\": \"https://s.hdnux.com/photos/01/17/27/54/20806403/6/rawImage.jpg\",\n      \"publishedAt\": \"2022-04-14T04:21:47Z\",\n      \"content\": \"This file photograph shows medical assistant Frencesca Delprete takes care of a driver during COVID-19 testing at the Alemany Farmers Market in San Francisco, Calif., on Monday, November 30, 2020.\\r\\nC… [+2006 chars]\"\n    },\n    {\n      \"source\": {\n        \"id\": \"national-geographic\",\n        \"name\": \"National Geographic\"\n      },\n      \"author\": \"Maya Wei-Haas\",\n      \"title\": \"The bizarre drama behind a pinch of moon dust that just sold for $500,000 - National Geographic\",\n      \"description\": \"Today’s auction is the culmination of a sordid saga involving Apollo astronauts, multiple lawsuits, and scientists aching for a chance to study rare lunar materials.\",\n      \"url\": \"https://www.nationalgeographic.com/science/article/the-bizarre-drama-behind-a-pinch-of-moon-dust-that-just-sold-for-500000\",\n      \"urlToImage\": \"https://i.natgeofe.com/n/f085ec36-dcfb-4473-914b-84905ab13c67/apollo11_0_16x9.jpg?w=1200\",\n      \"publishedAt\": \"2022-04-13T17:47:09Z\",\n      \"content\": \"On the precipice of humankind's first step on the moon, Neil Armstrong stood on the lunar module's ladder and described the grounds peculiar texture. Its almost like a powder, he told the Apollo Miss… [+9526 chars]\"\n    }\n  ]\n}\n"
  },
  {
    "path": "src/containers/apps/index.js",
    "content": "import React, {useState, useEffect} from 'react';\nimport {useSelector, useDispatch} from 'react-redux';\n\nimport './index.scss';\nimport './themes.scss';\n\nexport * from './whatsapp';\nexport * from './youtube';\nexport * from './playstore';\nexport * from './google';\n"
  },
  {
    "path": "src/containers/apps/index.scss",
    "content": ".app-wrapper{\n  pointer-events: auto;\n  height: 100%;\n  border-radius: 0;\n  transition: all 200ms ease-in-out;\n  animation: popup ease-in-out 200ms;\n\n  &[data-open=\"false\"]{\n    border-radius: 1em;\n    transform: scale(0.58);\n    opacity: 0;\n    pointer-events: none;\n\n    *{\n      pointer-events: none;\n    }\n  }\n}\n\n.app-inner-wrapper{\n  height: 100%;\n  overflow: hidden;\n  position: relative;\n}\n\n.app-icon-container{\n  height: 70%;\n  display: grid;\n  place-items: center;\n}\n\n@keyframes popup {\n  from{\n    border-radius: 1em;\n    transform: scale(0.8);\n    opacity: 0;\n  }\n\n  to{\n    border-radius: 0;\n    transform: scale(1);\n    opacity: 1;\n  }\n}\n\n.full-hide{\n  height: 100%;\n  overflow: hidden;\n}\n"
  },
  {
    "path": "src/containers/apps/playstore/index.js",
    "content": "import React, {useState, useEffect} from 'react';\nimport {useSelector, useDispatch} from 'react-redux';\n\nimport {Icon, Image, LazyComponent} from 'components/utils';\nimport {dispatchAction, dispatchAct} from 'store/actions';\n\nexport const PlaystoreApp = () => {\n  const app = useSelector(state => state.home.apps.playstore || {});\n  const home = useSelector(state => state.home);\n  const show = home.ishome==false && home.stack.at(-1)==app.payload;\n\n  return <AppContainer app={app} show={show}/>\n}\n\nconst AppContainer = ({app, show}) => {\n  const clstring = `${app.payload}-wrapper`;\n\n  return (\n    <div className={\"app-wrapper \"+clstring} id={clstring} data-open={show}>\n      <div className=\"app-icon-container\">\n        <Icon className=\"mdShad\" src={\"apps/\" + app.icon} w={72} action=\"home/setHome\"/>\n        <span>Playstore</span>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "src/containers/apps/themes.scss",
    "content": ".app-wrapper{\n  --app-bg: #fefefe;\n  background: var(--app-bg);\n}\n\n.whatsapp-wrapper, .playstore-wrapper{\n  --app-bg: #fefefe;\n  background: var(--app-bg);\n\n  --teal: #128c7e;\n  --teal-dark: #075e54;\n  --light-teal: #02a884;\n  --light-green: #25d366;\n  --white: #fefefe;\n  --blue: #34b7f1;\n  --check-blue: #34b7f1;\n  --link-blue: #5bc2df;\n  --bubble-green: #dcf8c6;\n}\n\n.whatsapp-viewport, .playstore-viewport{\n  --app-bg: #fefefe;\n  --teal: #128c7e;\n  --teal-dark: #075e54;\n\n  --statusbg: var(--teal);\n  --navbg: var(--app-bg);\n}\n\n.youtube-wrapper{\n  --app-bg: #fefefe;\n  --pm-txt: #121212;\n  background: var(--app-bg);\n  // color: #fefefe;\n}\n\n.youtube-viewport{\n  --app-bg: #fefefe;\n  --statusbg: var(--app-bg);\n  --navbg: var(--app-bg);\n}\n\n\n.google-wrapper{\n  --app-bg: #fefefe;\n  background: var(--app-bg);\n}\n\n.google-viewport{\n  --app-bg: #fefefe;\n\n  --statusbg: var(--app-bg);\n  --navbg: var(--app-bg);\n}\n"
  },
  {
    "path": "src/containers/apps/whatsapp/elements/extra.scss",
    "content": "// media player && status screen\n\n.media-viewer-container, .status-container{\n  position: absolute;\n  inset: 0;\n  background: #010101;\n  transition: all 200ms ease-in-out;\n\n  &[value=\"hide\"] {\n    opacity: 0;\n    pointer-events: none;\n  }\n\n  .whatsapp-top-nav {\n    background: none;\n    color: var(--comp-txt);\n    position: absolute;\n    top: 0;\n    padding: 0.5em;\n    z-index: 1;\n\n    .chat-name {\n      span:nth-child(1) {\n        font-size: 1.2em;\n      }\n\n      span:nth-child(2) {\n        font-size: 0.64em;\n        line-height: 0.75em;\n      }\n    }\n  }\n\n  .media-screen {\n    display: grid;\n    place-items: center;\n    height: 100%;\n\n    .vidCont {\n      height: 100%;\n    }\n\n    .video-control-container {\n      .MuiSlider-thumb,\n      .MuiSlider-track {\n        background: var(--light-teal);\n      }\n    }\n  }\n}\n\n.status-container{\n\n  .whatsapp-top-nav{\n    display: flex;\n    flex-direction: column;\n\n    .imageCont{\n      margin: 0 0.5em;\n    }\n  }\n\n  .status-msg-container{\n    height: 100%;\n    background: #2e92ee;\n    display: grid;\n    place-items: center;\n    padding: 1em;\n    text-align: center;\n    font-size: 2em;\n    color: var(--comp-txt);\n  }\n\n  .caption-container{\n    position: absolute;\n    bottom: 1.5em;\n    padding: 0.5em 0;\n    width: 100%;\n    color: var(--white);\n    background: rgba(1, 1, 1, 0.5);\n    font-weight: 500;\n    text-align: center;\n  }\n}\n\n.progress-bar-container{\n  display: flex;\n  height: 2px;\n  border-radius: 1em;\n  margin-bottom: 0.5em;\n\n  .progress-bar{\n    flex-grow: 1;\n    background: rgba(136, 136, 136, 0.5);\n    margin: 0 1.5px;\n    overflow: hidden;\n\n    &[data-lit=\"true\"]{\n      background: var(--white);\n    }\n\n    .progress-fill{\n      width: 0;\n      height: 100%;\n      background: var(--white);\n      transition: width 400ms linear;\n    }\n  }\n}\n\n// chat screen\n\n.chat-profile {\n  display: flex;\n  align-items: center;\n  padding: 0.2em;\n  border-radius: 2em;\n}\n\n.chat-screen-container {\n  position: absolute;\n  inset: 0;\n  --msg-incoming: #fefefe;\n  --msg-outgoing: #e7ffdd;\n  --msg-toast: #d3eaf7;\n  // --msg-outgoing: #e1ffc7;\n  .chat-screen {\n    flex-grow: 1;\n    overflow: hidden;\n  }\n\n  .chat-input-container {\n    display: flex;\n    align-items: flex-end;\n    padding: 0.2em 0.4em;\n\n    .chat-input-wrapper {\n      display: flex;\n      align-items: flex-end;\n      background: var(--white);\n      color: var(--mid-txt);\n      border-radius: 24px;\n      padding: 0.2em 0.4em;\n      flex-grow: 1;\n\n      .uicon {\n        margin: 0.36em 0.24em;\n      }\n    }\n\n    .chat-input-field {\n      padding: 0.2em;\n      flex-grow: 1;\n\n      & > div {\n        border: none;\n        padding: 0.3em 0;\n        color: var(--med-txt);\n      }\n\n      fieldset {\n        display: none;\n      }\n    }\n\n    .mic-icon,\n    .send-icon {\n      color: var(--white);\n      background: var(--light-teal);\n      height: 45px;\n      aspect-ratio: 1 / 1;\n      margin-left: 0.5em;\n      border-radius: 4em;\n    }\n\n    .mic-icon {\n      animation: pop-up ease-in-out 200ms;\n    }\n\n    .send-icon {\n      animation: pop-up2 ease-in-out 200ms;\n    }\n  }\n}\n\n.chat-container {\n  position: relative;\n  flex-grow: 1;\n  overflow-y: scroll;\n  padding: 0.5em 1em;\n\n  .chat-scroll-container {\n    // position: absolute;\n    min-height: 100%;\n    height: max-content;\n  }\n\n  .chat-toast {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n    // margin: 0.5em 0;\n    &[value=\"0\"] {\n      align-items: flex-start;\n    }\n\n    &[value=\"1\"] {\n      align-items: center;\n    }\n\n    &[value=\"2\"] {\n      align-items: flex-end;\n    }\n  }\n\n  .msg-box {\n    position: relative;\n    min-width: 4em;\n    max-width: 80%;\n    padding: 0.2em 0.3em;\n    border-radius: 0.5em;\n    margin: 0.125em 0;\n    font-size: 0.9em;\n\n    .imageCont {\n      margin-top: 0.125em;\n\n      img {\n        border-radius: 0.5em;\n      }\n    }\n\n    .vidCont {\n      margin-top: 0.125em;\n      border-radius: 0.5em;\n      overflow: hidden;\n    }\n\n    pre {\n      padding: 0 0.2em;\n      font-family: inherit;\n      white-space: pre-wrap;\n      word-wrap: break-word;\n      max-width: 100%;\n      color: var(--med-txt);\n\n      a {\n        color: var(--link-blue);\n        font-weight: 500;\n        white-space: pre-wrap;\n        overflow-wrap: break-word;\n      }\n    }\n\n    .chat-date {\n      margin-left: 0.5em;\n      margin-top: 0.5em;\n      float: right;\n      font-size: 0.7em;\n      font-weight: 500;\n      color: var(--sat-txt);\n      fill: var(--sat-txt);\n      display: flex;\n      align-items: center;\n\n      .uicon {\n        margin-left: 0.2em;\n        margin-bottom: 2px;\n      }\n    }\n\n    & > .chat-date {\n      position: absolute;\n      bottom: 0.5em;\n      right: 1em;\n      -webkit-text-stroke-color: #fefefe;\n      -webkit-text-stroke-width: thin;\n    }\n  }\n\n  .in-msg {\n    background: var(--msg-incoming);\n  }\n\n  .out-msg {\n    background: var(--msg-outgoing);\n  }\n\n  .first-msg {\n    margin-top: 0.5em;\n    position: relative;\n    z-index: 0;\n\n    &::after {\n      content: \"\";\n      position: absolute;\n      top: 0;\n      width: 1em;\n      height: 1.2em;\n      z-index: -1;\n    }\n  }\n\n  .in-msg.first-msg::after {\n    left: -0.5em;\n    background: var(--msg-incoming);\n    clip-path: polygon(0 0,100% 0,100% 100%);\n  }\n\n  .out-msg.first-msg::after {\n    right: -0.5em;\n    background: var(--msg-outgoing);\n    clip-path: polygon(0 0,100% 0,0 100%);\n  }\n\n  .msg-toast {\n    margin: 0.5em 0;\n    width: auto;\n    max-width: 90%;\n    padding: 0.2em 0.5em;\n    border-radius: 0.5em;\n    font-size: 0.72em;\n    text-align: center;\n    background: var(--msg-toast);\n    box-shadow: 1px 1px 1px rgba(18, 18, 18, 0.25);\n    word-spacing: 2px;\n  }\n}\n\n// all status\n.status-date {\n  font-size: 0.8em;\n  font-weight: 500;\n  color: var(--light-txt);\n}\n\n.my-status {\n  padding: 0.5em 0;\n\n  .chat-status {\n    margin: 0;\n  }\n}\n"
  },
  {
    "path": "src/containers/apps/whatsapp/elements/index.js",
    "content": "import React, {useState, useEffect, useRef} from 'react'\nimport {useSelector, useDispatch} from 'react-redux'\n\nimport TextField from '@mui/material/TextField'\n\nimport {Icon, Image, Video, isValidURL} from 'components/utils.js'\nimport {dispatchAction, dispatchAct} from 'store/actions'\n\nimport './extra.scss'\n\nexport const NavBar = (props)=>{\n  const [swidth, setWidth] = useState(0);\n  const [offLeft, setLeft] = useState(0);\n  const navbar = useRef();\n\n  useEffect(()=>{\n    if(navbar.current){\n      var childEle = navbar.current.children[props.tab];\n      var cwidth = getComputedStyle(childEle).width,\n          cleft = childEle.offsetLeft;\n\n      setWidth(cwidth)\n      setLeft(cleft)\n    }\n  }, [props.tab])\n\n  return (\n    <div className={`w-nav-tab ${props.className || \"\"}`} ref={navbar}>\n      {props.options && props.options.map((opt,i) => {\n        return (\n          <div className=\"tab-option active-light-lit prtclk\"  key={i}\n              value={props.tab == i} data-id={i} onClick={props.onClick}>\n            {opt}\n          </div>\n        )\n      })}\n      <div className=\"nav-slider\" style={{\n        width: swidth,\n        left: offLeft\n      }}></div>\n    </div>\n  )\n}\n\nexport const MediaViewer = () => {\n  const media = useSelector(state => state.whatsapp.media || {});\n\n  return (\n    <div className=\"media-viewer-container\" value={!media.vis && \"hide\"}>\n      <div className=\"whatsapp-top-nav\">\n        <div className=\"chat-profile-container flex items-center\">\n          <div className=\"chat-profile active-light-lit\">\n            <Icon mui=\"ArrowBack\" w={20} action=\"home/goBack\"/>\n          </div>\n          <div className=\"chat-name flex-column font-thin mx-4\">\n            <span>{media.name}</span>\n            <span>{new Date(media.time).pastdatetime()}</span>\n          </div>\n        </div>\n        <div className=\"w-nav-icons\">\n          <Icon mui=\"Reply\" flip/>\n          <Icon mui=\"MoreVert\"/>\n        </div>\n      </div>\n      <div className=\"media-screen\">\n        {media.type==\"Photo\" &&\n          <Image src={media.src} dir=\"asset/whatsapp/chats\"/>}\n        {media.type==\"Video\" && (\n          <Video src={media.src} dir=\"asset/whatsapp/chats\" h=\"100%\" cstmctrl/>\n        )}\n      </div>\n    </div>\n  )\n}\n\nexport const StatusScreen = ()=>{\n  const [idx, setIdx] = useState(0)\n  const [viewper, setPercent] = useState(0)\n  const [paused, setPaused] = useState(false)\n  const stdata = useSelector(state => state.whatsapp.status || {})\n  const contact = useSelector(state => {\n    var tmp = {}\n    if(stdata.id == -1) tmp = state.whatsapp.self\n    else tmp = state.whatsapp.chats && state.whatsapp.chats[stdata.id]\n    return tmp || {}\n  })\n\n  const photoProgressBool = ()=>{\n    return stdata.vis && contact.status && contact.status[idx].media!=\"Video\" && !paused;\n  }\n\n  const progressPhoto = ()=>{\n    if(!photoProgressBool()) return\n    if(viewper<idx+1) setPercent(viewper + 0.02)\n    else{\n      setPercent(idx+1)\n      if(idx < contact.status.length - 1){\n        setIdx(idx + 1)\n      }else{\n        setIdx(0)\n        dispatchAct({type: \"home/goBack\"})\n      }\n    }\n  }\n\n  const skipNext = ()=>{\n    // setPaused(true)\n    setPercent(idx+1)\n    if(idx < contact.status.length - 1){\n      setIdx(idx + 1)\n    }else{\n      setIdx(0)\n      dispatchAct({type: \"home/goBack\"})\n    }\n  }\n\n  const handleProg = (e)=>{\n    if(e.played<1) setPercent(idx + e.played)\n    else{\n      setPercent(idx+1)\n      if(idx < contact.status.length - 1){\n        setIdx(idx + 1)\n      }else{\n        setIdx(0)\n        dispatchAct({type: \"home/goBack\"})\n      }\n    }\n  }\n\n  useEffect(()=>{\n    if(photoProgressBool() && !paused){\n      setTimeout(progressPhoto, 100)\n    }\n  },[viewper,stdata.vis,idx,paused,contact.status])\n\n  useEffect(()=>{\n    if(!stdata.vis && (idx!=0 || viewper!=0)){\n      setIdx(0)\n      setPercent(0)\n    }\n\n    if(stdata.id){\n      dispatchAct({type: \"whatsapp/setViewStatus\", payload: {\n        id: stdata.id, count: idx + 1\n      }})\n    }\n  }, [stdata.vis, idx, viewper])\n\n  return (\n    <div className=\"status-container\" value={!stdata.vis && \"hide\"}>\n      <div className=\"whatsapp-top-nav\">\n        <div className=\"progress-bar-container\">\n          {stdata.vis && contact.status && contact.status.map((st,i) => {\n            return (\n              <div className='progress-bar' data-lit={i<idx} key={i}>\n                {i==idx && <div className=\"progress-fill\" style={{\n                  width: `${(viewper-i)*100}%`\n                }}></div>}\n              </div>\n            )\n          })}\n        </div>\n        <div className=\"chat-profile-container flex items-center\">\n          <div className=\"chat-profile active-light-lit\">\n            <Icon mui=\"ArrowBack\" w={20} action=\"home/goBack\"/>\n            <Image className=\"rounded-full overflow-hidden\"\n              src={contact.img} dir=\"asset/whatsapp/pfp\" w={36}/>\n          </div>\n          <div className=\"chat-name flex-column font-thin mb-1\">\n            <span>{stdata.id == -1 ? \"You\" : contact.name}</span>\n            <span>\n              {new Date(contact.status && contact.status.at(-1).time).minifyTime()}\n            </span>\n          </div>\n        </div>\n      </div>\n      {stdata.vis && contact.status?(\n        <>\n        <div className=\"media-screen prtclk\" onClick={skipNext}>\n          {contact.status[idx].media==\"Photo\" &&\n            <Image src={contact.status[idx].src} dir=\"asset/whatsapp/\"/>}\n          {contact.status[idx].media==\"Video\" && (\n            <Video src={contact.status[idx].src} h=\"100%\" dir=\"asset/whatsapp/\"\n              playIcon autoplay onProgress={handleProg} play={!paused}/>\n          )}\n          {contact.status[idx].msg && (\n            <div className=\"status-msg-container\">\n              {contact.status[idx].msg}\n            </div>\n          )}\n        </div>\n        {contact.status[idx].caption && (\n          <div className=\"caption-container\">{contact.status[idx].caption}</div>\n        )}\n        </>\n      ):null}\n    </div>\n  )\n}\n\nexport const AllStatusScreen = (props)=>{\n  const wdata = useSelector(state => state.whatsapp);\n  const myself = useSelector(state => state.whatsapp.self);\n  const contacts = useSelector(state => state.whatsapp.chats);\n\n  const CalculateArc = ({n,i,viewed})=>{\n    var gz = n==1 ? 0 : 3;\n    var dash = `${300/n - 2*gz}% ${300*(1 - 1/n) + 2*gz}%`,\n        offset = `${75 + 300*((i+1)/n) - 2*gz}%`\n\n    return (\n      <circle className={viewed?\"viewed\":\"notviewed\"} cx=\"52\" cy=\"52\"\n        r=\"50\" fill=\"none\" strokeLinecap=\"round\" strokeWidth=\"4\"\n        strokeDashoffset={offset} strokeDasharray={dash}></circle>\n    )\n  }\n\n  return (\n    <div className=\"chats-status-container medScroll\">\n      <div className=\"my-status active-dark-lit prtclk\" onClick={dispatchAction}\n        data-action=\"whatsapp/setStatus\" data-payload={-1}>\n        <div className=\"chat-status\">\n          <div className=\"status-preview-container\">\n            <div className=\"status-preview\">\n              <svg viewBox=\"0 0 104 104\" xmlns=\"http://www.w3.org/2000/svg\">\n                {myself && myself.status.map((status,i)=>{\n                  return <CalculateArc n={myself.status.length}\n                                        i={i} viewed key={i}/>\n                })}\n              </svg>\n            </div>\n            <Image className=\"rounded-full rounded\" src={myself && myself.img}\n                    dir=\"\" w={48}/>\n          </div>\n          <div className=\"status-info flex flex-col mx-4\">\n            <div className=\"chat-name\">My status</div>\n            <div className=\"status-date\">\n              {myself && new Date(myself.status.at(-1).time).minifyTime()}\n            </div>\n          </div>\n        </div>\n      </div>\n      <div className=\"gray-txt text-sm px-6\">Recent updates</div>\n      <div className=\"chats-status\">\n        {contacts && contacts.map((contact,i) => {\n          if(!contact.status || !contact.status.length) return null\n          return (\n            <div className=\"chat-status active-dark-lit prtclk\" data-payload={contact.id}\n              onClick={dispatchAction} data-action=\"whatsapp/setStatus\" key={contact.id}>\n              <div className=\"status-preview-container\">\n                <div className=\"status-preview\">\n                  <svg viewBox=\"0 0 104 104\" xmlns=\"http://www.w3.org/2000/svg\">\n                    {contact.status.map((status,i)=>{\n                      return <CalculateArc n={contact.status.length}\n                              i={i} key={i} viewed={status.seen}/>\n                    })}\n                  </svg>\n                </div>\n                <Image className=\"rounded-full rounded\" src={contact.img}\n                        dir=\"asset/whatsapp/pfp\" w={48}/>\n              </div>\n              <div className=\"status-info flex flex-col mx-4\">\n                <div className=\"chat-name\">{contact.name}</div>\n                <div className=\"status-date\">\n                  {new Date(contact.status.at(-1).time).minifyTime()}\n                </div>\n              </div>\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nexport const CallLogs = ()=>{\n  const wdata = useSelector(state => state.whatsapp);\n  const contacts = useSelector(state => state.whatsapp.chats);\n\n  return (\n    <div className=\"call-logs-container medScroll\">\n      <div className=\"call-logs\">\n        {contacts && contacts.map((chat,i) => {\n          var randv = chat.name.split(\"\").map(x => x.charCodeAt()).reduce((b,c) => 2*b + 3*c);\n          var callst = randv%3, callsticon = callst!=2?\"CallReceived\":\"CallMade\",\n              className = callst == 0? \"callMissed\":(callst==1?\"callConnected\":\"callMade\"),\n              minago = (randv*13)%1440, calltype = [\"ph\",\"vid\"][randv%2];\n\n          return(\n            <div className=\"call-log\" key={i}>\n              <Image className=\"rounded-full rounded\" src={chat.img} dir=\"asset/whatsapp/pfp\" w={48}/>\n              <div className=\"flex flex-col mx-4 flex-grow\">\n                <div className=\"chat-name\">{chat.name}</div>\n                <div className=\"status-date\">\n                  <Icon className={className} mui={callsticon} w={14}/>\n                  <span>{new Date().minifyTime(minago)}</span>\n                </div>\n              </div>\n              {calltype==\"ph\"?<Icon className=\"teal-green\" mui=\"Call\" rounded/>:\n                              <Icon className=\"teal-green\" mui=\"Videocam\"/>}\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nexport const ChatScreen = (props)=>{\n  const [msg, setMsg] = useState('');\n  const chatscreen = useRef();\n  const wdata = useSelector(state => state.whatsapp);\n  const contact = useSelector(state => {\n    return (\n      state.whatsapp.chats && state.whatsapp.chats[state.whatsapp.curr]\n    ) || {}\n  })\n\n  const handleMsg = (e)=>{\n    setMsg(e.target.value)\n  }\n\n  const mediaHandler = (e)=>{\n    var ele = e.target;\n    const payload = {\n      type: ele.dataset.type,\n      src: ele.dataset.src,\n      name: ele.dataset.name,\n      time: ele.dataset.time\n    }\n\n    dispatchAct({type: \"whatsapp/setMedia\", payload: payload})\n  }\n\n  const processLinks = (txt)=>{\n    var arr = txt.split(' '), tmp = [], txtstr = [];\n\n    for (var i = 0; i < arr.length; i++) {\n      try{\n        var url = (!arr[i].startsWith(\"http\") ? \"https://\":\"\") + arr[i] ,\n            urlobj = null;\n\n        if(isValidURL(url)) urlobj = new URL(url)\n        if(!urlobj) throw new Error()\n\n        if(txtstr.length) tmp.push(txtstr.join(' '))\n        txtstr = []\n        tmp.push(<a href={urlobj.href} target=\"_blank\" key={i}> {arr[i]} </a>)\n      }catch(e){\n        txtstr.push(arr[i])\n      }\n    }\n\n    if(txtstr.length) tmp.push(txtstr.join(' '))\n\n    return tmp\n  }\n\n  const sendMessage = ()=>{\n    dispatchAct({\n      type: \"whatsapp/sendMsg\",\n      payload: {\n        id: wdata.curr,\n        msg: msg\n      }\n    })\n\n    setMsg(\"\")\n  }\n\n  const scrollToEnd = ()=>{\n    chatscreen.current.scrollBy(0, chatscreen.current.scrollHeight + 100)\n  }\n\n  useEffect(()=>{\n    if(props.checkstate('chat') && chatscreen.current){\n      scrollToEnd()\n      setTimeout(scrollToEnd, 200)\n      dispatchAct({type: \"whatsapp/setChatProp\", payload: {\n        id: wdata.curr,\n        key: \"seen\",\n        value: true\n      }})\n    }\n  }, [wdata.curr, contact.chat])\n\n  return(\n    <div className=\"chat-screen-container flex-column scale-trans\"\n        data-vis={props.checkstate('chat')}>\n      <div className=\"whatsapp-top-nav downbug\">\n        <div className=\"chat-profile-container flex items-center\">\n          <div className=\"chat-profile prtclk active-light-lit\"\n            onClick={dispatchAction} data-action=\"home/goBack\">\n            <Icon mui=\"ArrowBack\" w={20}/>\n            <Image className=\"rounded-full overflow-hidden\"\n                  src={contact.img} dir=\"asset/whatsapp/pfp\" w={36}/>\n          </div>\n          <div className=\"chat-name text-lg font-thin mx-2\">{contact.name}</div>\n        </div>\n        <div className=\"w-nav-icons\">\n          <Icon mui=\"Videocam\"/>\n          <Icon mui=\"Call\" w={20} rounded/>\n          <Icon mui=\"MoreVert\"/>\n        </div>\n      </div>\n      <div className=\"chat-screen flex-column\" style={{\n        background: 'url(/img/asset/whatsapp/background.png)'\n      }}>\n        <div className=\"chat-container medScroll\" ref={chatscreen}>\n          <div className=\"chat-scroll-container\">\n            <div className=\"chat-toast\" value=\"1\">\n              <div className=\"msg-toast\">\n                🔓 Messages and calls are end-to-end open. It's Facebook, what else would you expect. Privacy go brrr.\n              </div>\n            </div>\n            {contact.chat && contact.chat.map((item, i) => {\n              var arr = [], prev = i>0 && contact.chat[i-1];\n\n              if(i==0 || new Date(prev.time).getDate() != new Date(item.time).getDate()){\n                arr.push(\n                  <div className=\"chat-toast\" value=\"1\" key={\"msg-\"+i}>\n                    <div className=\"msg-toast\">\n                      {new Date(item.time).pastdate()}\n                    </div>\n                  </div>\n                )\n              }\n\n              arr.push(\n                <div className=\"chat-toast\" value={item.type} key={i}>\n                  {item.type!=\"1\"?(\n                    <div className={'msg-box ' +\n                      (item.type=='0'?'in-msg':'out-msg') +\n                      (!prev || prev.type!=item.type ? ' first-msg':'')\n                    }>\n                      {item.media==\"Photo\"?(\n                        <Image src={item.src} dir=\"asset/whatsapp/chats\"\n                          data-type={item.media} data-name={\n                            item.type=='0'? (item.name || contact.name): \"You\"\n                          } onClick={mediaHandler} data-time={item.time}\n                          data-src={item.src}/>\n                      ):null}\n                      {item.media==\"Video\"?(\n                        <Video\n                          src={item.src} inactive\n                          dir=\"asset/whatsapp/chats\"\n                          data-type={item.media} data-name={\n                            item.type=='0'? (item.name || contact.name): \"You\"\n                          } onClick={mediaHandler}\n                          data-time={item.time}\n                          data-src={item.src}/>\n                      ):null}\n                      {item.msg?(\n                        <pre>\n                          {processLinks(item.msg)}\n                          <div className=\"chat-date\">\n                            <span>{new Date(item.time || 0).time12()}</span>\n                            {item.type==\"2\"?(\n                              item.seen?<Icon className=\"seentick\" icon=\"seentick\" w={14} payload={item.seen}/>:\n                                  <Icon className=\"seentick\" mui=\"Done\" w={14} payload={0}/>\n                            ):null}\n                          </div>\n                        </pre>\n                      ):(\n                        <div className=\"chat-date\">\n                          <span>{new Date(item.time || 0).time12()}</span>\n                          {item.type==\"2\"?(\n                            item.seen?<Icon className=\"seentick\" icon=\"seentick\" w={14} payload={item.seen}/>:\n                                <Icon className=\"seentick\" mui=\"Done\" w={14} payload={0}/>\n                          ):null}\n                        </div>\n                      )}\n                    </div>\n                  ):(\n                    <div className=\"msg-toast\">{item.msg}</div>\n                  )}\n                </div>\n              )\n\n              return arr\n            })}\n          </div>\n        </div>\n        <div className=\"chat-input-container\">\n          <div className=\"chat-input-wrapper\">\n            <Icon mui=\"EmojiEmotions\" out/>\n            <TextField className=\"chat-input-field\" multiline maxRows={4}\n              placeholder=\"Message\" value={msg} onChange={handleMsg}/>\n            <Icon mui=\"AttachFile\"/>\n            {msg.length==0?<Icon className=\"CameraIcon\" mui=\"PhotoCamera\" round/>:null}\n          </div>\n          {msg.length==0?(\n            <Icon className=\"mic-icon\" mui=\"Mic\" h={24}/>\n          ):<Icon className=\"send-icon press-in\" mui=\"Send\" h={24} onClick={sendMessage}/>}\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport const AllContacts = (props)=>{\n  const wdata = useSelector(state => state.whatsapp);\n  const contacts = useSelector(state => state.whatsapp.chats || []);\n\n  const clickContact = (e)=>{\n    var id = e.target.getAttribute(\"value\");\n\n    dispatchAct({\n      type: \"whatsapp/setProp\",\n      payload: {key: \"curr\", value: id}\n    })\n\n    dispatchAct({\n      type: \"home/navApp\",\n      payload: \"whatsapp.chat\"\n    })\n  }\n\n  return (\n    <div className=\"contacts-container scale-trans\"\n        data-vis={props.checkstate('contact')}>\n      <div className=\"whatsapp-top-nav\">\n        <div className=\"chat-profile-container flex items-center\">\n          <div className=\"chat-profile active-light-lit\">\n            <Icon mui=\"ArrowBack\" w={20} action=\"home/goBack\"/>\n          </div>\n          <div className=\"chat-name flex-column font-thin mx-4\">\n            <span className=\"text-lg\">Select Contacts</span>\n            <span className=\"text-xs\">\n              {contacts.length} contact{contacts.length>1?\"s\":\"\"}\n            </span>\n          </div>\n        </div>\n        <div className=\"w-nav-icons\">\n          <Icon mui=\"Search\"/>\n          <Icon mui=\"MoreVert\"/>\n        </div>\n      </div>\n      <div className=\"all-contacts medScroll\">\n        <div className=\"contact-cotainer active-dark-lit prtclk\">\n          <Icon className=\"rounded-full rounded\" mui=\"Group\" w={24}/>\n          <div className=\"flex flex-col ml-4 flex-grow\">\n            <div className=\"chat-name\">New group</div>\n          </div>\n        </div>\n        <div className=\"contact-cotainer active-dark-lit prtclk\">\n          <Icon className=\"rounded-full rounded\" mui=\"PersonAdd\" w={22}/>\n          <div className=\"flex flex-col ml-4 flex-grow\">\n            <div className=\"chat-name\">New contact</div>\n          </div>\n        </div>\n        {contacts && [...contacts].sort((a,b)=> {\n          return a.name>b.name?1:-1\n        }).map(contact => {\n          return(\n            <div className=\"contact-cotainer active-dark-lit prtclk\"\n                  key={contact.id} onClick={clickContact} value={contact.id}>\n              <Image className=\"rounded-full rounded\"\n                src={contact.img} dir=\"asset/whatsapp/pfp\" w={38}/>\n              <div className=\"flex flex-col ml-4 flex-grow\">\n                <div className=\"chat-name\">{contact.name}</div>\n                <div className=\"status-date\">\n                  {contact.bio}\n                </div>\n              </div>\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "src/containers/apps/whatsapp/index.js",
    "content": "import React, {useState, useEffect, useRef} from 'react';\nimport {useSelector, useDispatch} from 'react-redux';\n\nimport {Icon, Image, LazyComponent} from 'components/utils';\nimport {dispatchAction, dispatchAct} from 'store/actions';\nimport Swiper from 'react-slick';\n\nimport './whatsapp.scss';\n\nimport {\n  NavBar,\n  AllStatusScreen,\n  AllContacts,\n  StatusScreen,\n  ChatScreen,\n  CallLogs,\n  MediaViewer\n} from './elements'\n\nexport const WhatsappApp = () => {\n  const app = useSelector(state => state.home.apps.whatsapp || {});\n  const home = useSelector(state => state.home);\n  const show = home.ishome==false && home.stack.at(-1)==app.payload;\n  const pagetree = app && app.pagetree || {\n    \"main\": {\n      \"chat\" : {},\n      \"contact\" : {}\n    }\n  }\n\n  useEffect(()=>{\n    if(app && !app.pagetree){\n      dispatchAct({type: \"home/setApp\", payload: {\n        id: app.payload,\n        data: {\n          ... app,\n          pagetree: pagetree,\n          path: ['main']\n        }\n      }})\n    }\n  }, [app])\n\n  return <AppContainer app={app} show={show}/>\n}\n\nconst AppContainer = ({app, show}) => {\n  const [tab, setTab] = useState(1);\n  const homeSwiper = useRef();\n  const clstring = `${app.payload}-wrapper`;\n  const path = app.path || [\"main\"];\n\n  const tabSetter = (hmswiper)=>{\n    if(!hmswiper) return\n    var swidth = hmswiper.style.width,\n        swleft = hmswiper.style.transform;\n\n    swidth = swidth.replace(\"px\",\"\")\n    swleft = swleft.replace(\"translate3d(\",\"\").replace(\"px, 0px, 0px)\",\"\")\n\n    try{\n      swidth = parseInt(swidth)\n      swleft = Math.abs(parseInt(swleft))\n\n      var tb = Math.round((swleft*4)/swidth)\n      tb = Math.max(0, Math.min(3, tb))\n      setTab(tb)\n    }catch(err){\n      console.log(err)\n    }\n  }\n\n  const clickTabHandler = (e)=>{\n    var id = e.target.dataset.id\n    if(homeSwiper.current){\n      setTab(id)\n      homeSwiper.current.slickGoTo(id, false)\n    }\n  }\n\n  const swipehandler = ()=>{\n    if(homeSwiper.current){\n      var hmswiper = document.querySelector('.app-wrapper .whatsapp-home-swiper .slick-track');\n      tabSetter(hmswiper)\n      setTimeout(()=>{\n        tabSetter(hmswiper)\n      },200)\n    }\n  }\n\n  const checkstate = (comp) => {\n    return path.includes(comp) ? (\n      path.at(-1) == comp ? 1 : 2\n    ) : 0;\n  }\n\n  return (\n    <div className={\"app-wrapper \" + clstring} id={clstring} data-open={show}>\n      <div className=\"app-inner-wrapper wp-inner-wrapper\">\n        <div className='whatsapp-home full-hide upbug scale-trans' data-vis={checkstate('main')}>\n          <div className=\"whatsapp-top-nav downbug\">\n            <div className=\"brand-name\">WhatsApp</div>\n            <div className=\"w-nav-icons\">\n              <Icon mui=\"Search\"/>\n              <Icon mui=\"MoreVert\"/>\n            </div>\n          </div>\n          <NavBar className=\"home-nav-tab\" tab={tab} options={[\n            <Icon mui=\"PhotoCamera\" round w={22}/>,\"CHATS\",\"STATUS\",\"CALLS\"\n          ]} onClick={clickTabHandler}/>\n          <div className=\"whatsapp-home-page\">\n            <Swiper className=\"whatsapp-home-swiper full-height-swiper\" {...{\n              dots: false,\n              arrows: false,\n              infinite: false,\n              initialSlide: tab,\n              speed: 200\n            }} onSwipe={swipehandler} ref={homeSwiper}>\n              <CameraScreen/>\n              <AllChatScreen/>\n              <AllStatusScreen/>\n              <CallLogs/>\n            </Swiper>\n            {tab!=0 && (\n              <div className=\"quick-wtool-container press-in\">\n                {tab==1 && <Icon action=\"home/navApp\" mui=\"Chat\"\n                              payload=\"whatsapp.contact\" w={24}/>}\n                {tab==2 && <Icon mui=\"PhotoCamera\" round w={24}/>}\n                {tab==3 && <Icon mui=\"AddIcCall\" rounded w={24}/>}\n              </div>\n            )}\n          </div>\n        </div>\n        <ChatScreen checkstate={checkstate}/>\n        <AllContacts checkstate={checkstate}/>\n        <MediaViewer/>\n        <StatusScreen/>\n      </div>\n    </div>\n  );\n}\n\nconst CameraScreen = ()=>{\n  return (\n    <div className=\"camera-container\"></div>\n  )\n}\n\nconst AllChatScreen = ()=>{\n  const wdata = useSelector(state => state.whatsapp);\n  const contacts = useSelector(state => state.whatsapp.chats);\n\n  const clickChat = (e)=>{\n    var id = e.target.getAttribute(\"value\");\n\n    dispatchAct({\n      type: \"whatsapp/setProp\",\n      payload: {key: \"curr\", value: id}\n    })\n\n    dispatchAct({\n      type: \"home/navApp\",\n      payload: \"whatsapp.chat\"\n    })\n  }\n\n  useEffect(()=>{\n    dispatchAct({type: 'home/setAppKey', payload:{\n      id: 'whatsapp', key: 'comp', value: wdata.comp\n    }})\n  }, [wdata.comp])\n\n  return (\n    <div className=\"home-chats-container medScroll\">\n      <div className=\"home-chats\">\n        {contacts && [...contacts].sort((a,b)=>{\n          if(!a.chat || !b.chat) return 1\n          if(!a.chat.length) return -1\n          if(!b.chat.length) return 1\n\n          var a_lastmsg = a.chat.at(-1),\n              b_lastmsg = b.chat.at(-1)\n\n          var a_seen = a_lastmsg.type==\"0\" && !a.seen,\n              b_seen = b_lastmsg.type==\"0\" && !b.seen\n\n          if(a_seen ^ b_seen){\n            if(!a_seen) return 1\n            else return -1\n          }else{\n            if(new Date(a_lastmsg.time) > new Date(b_lastmsg.time)) return -1\n            else return 1\n          }\n        }).map((contact,i) => {\n          if(!contact.chat || !contact.chat.length) return null\n          var lastmsg = contact.chat.at(-1)\n\n          return(\n            <div className=\"all-chat-container prtclk active-dark-lit\"\n                key={contact.id} onClick={clickChat} value={contact.id}>\n              <Image src={contact.img} dir=\"asset/whatsapp/pfp\" w={48}/>\n              <div className=\"short-info\">\n                <div className=\"chat-info\">\n                  <div className=\"chat-name\">{contact.name}</div>\n                  <div className=\"chat-date\">{new Date(lastmsg.time).time12()}</div>\n                </div>\n                <div className=\"latest-message-container\">\n                  <div className=\"latest-message\">\n                    {lastmsg.type==\"2\"?(\n                      <Icon className=\"seentick\" mui={lastmsg.seen==0?\"Done\":null}\n                        icon={lastmsg.seen>0?\"seentick\":null} w={14} payload={lastmsg.seen}/>\n                    ):null}\n                    {lastmsg.media==\"Photo\"?<Icon mui=\"Photo\" w={14}/>:null}\n                    {lastmsg.media==\"Video\"?<Icon mui=\"Videocam\" w={14}/>:null}\n                    <span className=\"last-msg-txt\">{lastmsg.msg || lastmsg.media}</span>\n                  </div>\n                  <div className=\"chat-acts\">\n                    {lastmsg.type==\"0\" && !contact.seen && <div className=\"unread\">{1}</div>}\n                    {/* {i<3 ? <Icon icon=\"pinned\" fill=\"#687881\"/>: null} */}\n                  </div>\n                </div>\n              </div>\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "src/containers/apps/whatsapp/whatsapp.scss",
    "content": ".teal-green {\n  color: var(--teal);\n}\n\n.wp-inner-wrapper {\n  // font-family: \"Sans-serif\";\n}\n\n.whatsapp-home {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n}\n\n.whatsapp-top-nav {\n  width: 100%;\n  display: flex;\n  position: relative;\n  justify-content: space-between;\n  padding: 0.5em 0.6em 0.5em 0.2em;\n  background: var(--teal);\n  color: var(--white);\n\n  .brand-name {\n    font-weight: 400;\n    font-size: 1.25em;\n    padding-left: 0.4em;\n    letter-spacing: 1px;\n  }\n\n  .w-nav-icons {\n    display: flex;\n\n    .uicon {\n      margin-left: 1em;\n    }\n  }\n}\n\n.w-nav-tab {\n  width: 100%;\n  display: flex;\n  justify-content: space-between;\n  position: relative;\n\n  .nav-slider {\n    height: 4px;\n    position: absolute;\n    background: var(--white);\n    bottom: 0;\n    transition: all 200ms ease-in-out;\n  }\n\n  .tab-option {\n    font-weight: 200;\n    font-size: 0.88em;\n    padding: 0.5em;\n    opacity: 0.5;\n    flex-grow: 1;\n    text-align: center;\n    margin: 0 0.5em;\n\n    &[value=\"true\"] {\n      opacity: 1;\n    }\n  }\n}\n\n.home-nav-tab {\n  background: var(--teal);\n  color: var(--white);\n\n  .tab-option:first-child {\n    flex-grow: 0;\n    margin: 0;\n  }\n}\n\n.whatsapp-home-page {\n  width: 100%;\n  flex-grow: 1;\n  overflow: hidden;\n\n  .call-logs-container,\n  .chats-status-container,\n  .home-chats-container {\n    height: 100%;\n    overflow-y: scroll;\n  }\n}\n\n.home-chats {\n  height: max-content;\n  padding: 0.5em;\n  color: var(--med-txt);\n\n  .all-chat-container {\n    padding: 0.5em 0;\n    display: flex;\n\n    .short-info {\n      flex-grow: 1;\n      margin-left: 0.8em;\n      position: relative;\n    }\n\n    .imageCont {\n      border-radius: 50%;\n      overflow: hidden;\n    }\n\n    .chat-info {\n      display: flex;\n\n      .chat-name {\n        flex-grow: 1;\n        font-size: 1.1em;\n        font-weight: 600;\n      }\n\n      .chat-date {\n        font-size: 0.72em;\n        font-weight: 400;\n        color: var(--sat-txt);\n      }\n    }\n\n    .latest-message-container {\n      display: flex;\n      position: absolute;\n      width: 100%;\n    }\n\n    .latest-message {\n      flex-grow: 1;\n      display: flex;\n      font-size: 0.84em;\n      font-weight: 500;\n      color: var(--sat-txt);\n      fill: var(--sat-txt);\n      position: relative;\n      max-width: 100%;\n\n      .uicon {\n        margin-right: 0.2em;\n      }\n\n      span {\n        overflow: hidden;\n        display: -webkit-box;\n        -webkit-line-clamp: 1;\n        -webkit-box-orient: vertical;\n        text-overflow: ellipsis;\n      }\n    }\n\n    .chat-acts {\n      display: flex;\n\n      .unread {\n        font-size: 0.64em;\n        padding: 0.2em 0.76em;\n        border-radius: 50%;\n        margin: 0 0.5em;\n        color: var(--white);\n        background: var(--light-green);\n      }\n    }\n  }\n}\n\n.seentick {\n  &[data-payload=\"2\"] {\n    color: var(--blue);\n    fill: var(--blue);\n  }\n}\n\n.quick-wtool-container {\n  position: absolute;\n  bottom: 1em;\n  right: 1em;\n  padding: 0.8em;\n  border-radius: 3em;\n  background: var(--light-teal);\n  color: var(--white);\n}\n\n.camera-container {\n  height: 100%;\n  overflow: hidden;\n  background: black;\n}\n\n.all-contacts,\n.call-logs,\n.chats-status,\n.my-status {\n  height: max-content;\n  color: var(--med-txt);\n\n  .call-log,\n  .chat-status,\n  .contact-cotainer {\n    display: flex;\n    align-items: center;\n    padding: 0.5em 1em;\n    // margin-bottom: 1em;\n    .status-preview-container {\n      position: relative;\n      // background: var(--teal);\n      border-radius: 50%;\n      padding: 3px;\n      // overflow: hidden;\n      .status-preview {\n        position: absolute;\n        width: 100%;\n        height: 100%;\n        inset: 0;\n        // transform: scale(-1, 1);\n        svg {\n          width: 100%;\n          height: 100%;\n        }\n\n        .notviewed {\n          stroke: var(--teal);\n        }\n\n        .viewed {\n          stroke: var(--light-txt);\n        }\n      }\n\n      .imageCont {\n        border: 1px solid var(--white);\n      }\n    }\n  }\n}\n\n.call-logs {\n  padding-top: 0.5em;\n\n  .status-date {\n    display: flex;\n\n    .callConnected,\n    .callMade {\n      color: var(--light-green);\n    }\n\n    .callMissed {\n      color: #eb3434;\n    }\n  }\n}\n\n.scale-trans {\n  opacity: 1;\n  transform: scale(1);\n  transition: 200ms ease-in-out;\n  pointer-events: auto;\n  transition-property: transform, opacity;\n\n  &[data-vis=\"0\"] {\n    transform: scale(0.9);\n    pointer-events: none;\n    opacity: 0;\n  }\n\n  &[data-vis=\"2\"] {\n    transform: scale(1.1);\n    pointer-events: none;\n    opacity: 0;\n  }\n}\n\n// all contacts container\n.contacts-container {\n  position: absolute;\n  inset: 0;\n\n  .contact-cotainer {\n    .imageCont, .uicon{\n      min-width: 38px;\n      min-height: 38px;\n      color: #fefefe;\n      background: var(--light-teal);\n    }\n  }\n}\n\n.all-contacts {\n  padding-top: 0.5em;\n  height: 100%;\n  overflow-y: scroll;\n\n  .status-date {\n    flex-grow: 1;\n    overflow: hidden;\n    display: -webkit-box;\n    -webkit-line-clamp: 1;\n    -webkit-box-orient: vertical;\n    text-overflow: ellipsis;\n  }\n}\n"
  },
  {
    "path": "src/containers/apps/youtube/extra.js",
    "content": "import React, {useState, useEffect, useRef} from 'react';\nimport {useSelector, useDispatch} from 'react-redux';\n\nimport {Icon, Image, Video} from 'components/utils.js';\nimport {dispatchAction, dispatchAct} from 'store/actions';\nimport './extra.scss';\n\nconst posneg = (a,b,seed) => {\n  var sa = a.csum(), sb = b.csum(), sd = seed.csum()\n  return (sa + sb)%2 == sd%2==0 ? 1:-1\n}\n\nconst pseudorandom = (arr,seed)=>{\n  arr = arr.filter(x => x!= seed)\n  return arr.sort((a,b) => posneg(a,b,seed))\n}\n\nexport const ViewPage = (props)=>{\n  const [liked, setLiked] = useState(-1)\n  const [loadSugg, setLoad] = useState(false)\n  const ytwatch = useRef()\n  const ydata = useSelector(state => state.youtube)\n  const watvid = useSelector(state => {\n    var id = state.youtube.watch && state.youtube.watch.id\n    return state.youtube.vids && state.youtube.vids[id]\n  })\n\n  const vidch = useSelector(state => {\n    var id = state.youtube.watch && state.youtube.watch.id,\n        channel = {...state.youtube.channels && state.youtube.channels[\n          state.youtube.vids[id] && state.youtube.vids[id].channel\n        ]}\n\n    if(channel) channel.subd = state.youtube.subd && state.youtube.subd.includes(channel.id)\n    return channel\n  })\n\n  const handleFullReq = (e)=>{\n    if(ydata.comp) return\n    dispatchAct({type: 'youtube/setProp', payload:{\n      key: 'comp', value: true\n    }})\n  }\n\n  const handleLike = (e)=>{\n    setLiked(e.target.dataset.payload)\n  }\n\n  useEffect(()=>{\n    if(watvid && watvid.id){\n      setLoad(true)\n      setLiked(-1)\n      if(ytwatch.current) ytwatch.current.scrollTo(0,0)\n      setTimeout(()=> {\n        setLoad(false)\n      }, 1000)\n    }\n  },[watvid])\n\n  useEffect(()=>{\n    dispatchAct({type: 'home/setAppKey', payload:{\n      id: 'youtube', key: 'comp', value: ydata.comp\n    }})\n  }, [ydata.comp])\n\n  return watvid ? (\n    <div className={`yt-vid-view ${!ydata.comp ? 'mini-yt-vid':''}`}>\n      <div className=\"yt-vid-box\">\n        <Video src={\"https://youtube.com/embed/\"+watvid.id}\n                playIcon w=\"100%\" h=\"100%\"/>\n      </div>\n      <div className=\"yt-watch-container\" ref={ytwatch}>\n        <div className=\"yt-vid-info\" onClick={handleFullReq}>\n          <div className=\"vid-title txt-ovf\">{watvid.title}</div>\n          <div className=\"vid-stat\">\n            {ydata.comp ? (\n              `${watvid.views.quantf()} views • ${new Date(watvid.upload).minifyDate()}`\n            ): `${vidch.name}`}\n          </div>\n          {ydata.comp && (\n            <div className=\"vid-acts\">\n              <div className=\"flex flex-col items-center prtclk\"\n                      onClick={handleLike} data-payload=\"1\">\n                <Icon mui=\"ThumbUp\" out={liked!=1}/>\n                <span>{watvid.likes.quantf()}</span>\n              </div>\n              <div className=\"flex flex-col items-center prtclk\"\n                      onClick={handleLike} data-payload=\"0\">\n                <Icon mui=\"ThumbDown\" out={liked!=0}/>\n                <span>{watvid.dislikes.quantf()}</span>\n              </div>\n              <div className=\"flex flex-col items-center\">\n                <Icon mui=\"Reply\" flip/><span>Share</span>\n              </div>\n              <div className=\"flex flex-col items-center\">\n                <Icon mui=\"Download\"/><span>Download</span>\n              </div>\n              <div className=\"flex flex-col items-center\">\n                <Icon mui=\"LibraryAdd\" out/><span>Save</span>\n              </div>\n            </div>\n          )}\n        </div>\n        {!ydata.comp && (\n          <div className=\"yt-mini-ctrl\">\n            <Icon className=\"mx-1\" mui=\"PlayArrow\" w={28} onClick={handleFullReq}/>\n            <Icon className=\"mx-1\" mui=\"Close\" w={28} action=\"youtube/closeVid\"/>\n          </div>\n        )}\n        {ydata.comp && (\n          <>\n          <div className=\"yt-channel-row\">\n            <div className=\"flex items-center\">\n              <Image src={vidch.pfp} dir=\"asset/youtube/pfp\" w={36}/>\n              <div>\n                <div className=\"leading-4\">{vidch.name}</div>\n                <div className=\"text-xss light-txt\">{vidch.subs.quantf()} subscribers</div>\n              </div>\n            </div>\n            <div className=\"subscribed-container\">\n              <div className={`text-sm mr-4 ${!vidch.subd?'red-txt':''}`} onClick={dispatchAction}\n                  data-action=\"youtube/toggleSub\" data-payload={vidch.id}>\n                {vidch.subd ? \"SUBSCRIBED\":\"SUBSCRIBE\"}\n              </div>\n              {vidch.subd && <Icon mui=\"NotificationsActive\"/>}\n            </div>\n          </div>\n          <div className=\"yt-comment-box\">\n            <div className=\"text-sm\">Comments are turned off&nbsp;\n              {/* <span className=\"light-txt font-thin text-sm\">{269}</span> */}\n            </div>\n          </div>\n          <div className=\"yt-sugg-container\">\n            {!loadSugg && ydata.home && pseudorandom(ydata.home, watvid.id).splice(0,10).map((item,i)=>{\n              var vid = ydata.vids[item],\n                  channel = ydata.channels[vid.channel] || {}\n\n              return (\n                <div className=\"yt-item-container prtclk\" onClick={dispatchAction}\n                  data-action=\"youtube/watchVideo\" data-payload={vid.id} key={i}>\n                  <div className=\"yt-vid-thumbnail\">\n                    <Image src={vid.thumb} dir=\"asset/youtube/thumbs\"/>\n                  </div>\n                  <div className=\"yt-vid-info\">\n                    <Image src={channel.pfp} dir=\"asset/youtube/pfp\" w={36}/>\n                    <div className=\"flex-grow pl-2\">\n                      <div className=\"txt-ovf yt-vid-title\">{vid.title}</div>\n                      <div className=\"yt-vid-extra\">\n                        {channel.name} • {vid.views.quantf()} views • {new Date(vid.upload).minifyDate()}\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              )\n            })}\n            {loadSugg && (\n              <div className=\"yt-item-container\">\n                <div className=\"yt-vid-thumbnail\">\n                  <Image src=\"\" dir=\"asset/youtube/thumbs\"/>\n                </div>\n              </div>\n            )}\n          </div>\n          </>\n        )}\n      </div>\n    </div>\n  ) : null\n}\n\nexport const TrendingPage = (props)=>{\n  const ydata = useSelector(state => state.youtube)\n  const [tab, setTab] = useState(0)\n\n  const changeTab = (e) => setTab(e.target.dataset.id)\n  const catg = [\"Trending\", \"Music\", \"Gaming\", \"News\", \"Fashion and Beauty\", \"Learning\"]\n\n  return (\n    <div className=\"yt-page yt-trending-page\">\n      <div className=\"yt-trending-catg\">\n        {catg.map((item, i) => {\n          return (\n            <div className=\"yt-catg prtclk softpress-in\" key={item} data-id={i} onClick={changeTab}>\n              <img src={\"img/icon/other/\" + item.toLowerCase().split(\" \")[0] + \".svg\"} alt=\"yticon\"/>\n              <span>{item}</span>\n            </div>\n          )\n        })}\n      </div>\n      <hr/>\n      <div className=\"yt-trending-container\">\n        <div className=\"yt-trending-title p-4\">{catg[tab]}</div>\n        {ydata.explore && ydata.explore[catg[tab].toLowerCase().split(\" \")[0]].map((item,i)=>{\n          var vid = ydata.vids[item],\n              channel = ydata.channels[vid.channel] || {}\n\n          return (\n            <div className=\"yt-item-container prtclk\" onClick={dispatchAction}\n              data-action=\"youtube/watchVideo\" data-payload={vid.id} key={i}>\n              <div className=\"yt-vid-thumbnail\">\n                <Image src={vid.thumb} dir=\"asset/youtube/thumbs\"/>\n              </div>\n              <div className=\"yt-vid-info\">\n                <Image src={channel.pfp} dir=\"asset/youtube/pfp\" w={36}/>\n                <div className=\"flex-grow pl-2\">\n                  <div className=\"txt-ovf yt-vid-title\">{vid.title}</div>\n                  <div className=\"yt-vid-extra\">\n                    {channel.name} • {vid.views.quantf()} views • {new Date(vid.upload).minifyDate()}\n                  </div>\n                </div>\n              </div>\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nexport const SubsPage = (props)=>{\n  const [chid, setId] = useState(\"\")\n  const ydata = useSelector(state => state.youtube)\n\n  const handleChClick = (e)=>{\n    var id = e.target.dataset.id\n    if(chid==id) setId(\"\")\n    else setId(id)\n  }\n\n  return (\n    <div className=\"yt-page\">\n      <div className=\"yt-subs-container\">\n        <div className=\"yt-channels-sc noscroll\">\n          <div className=\"yt-ch-body\">\n            {ydata.subd && ydata.subd.map((item, i)=>{\n              var channel = ydata.channels[item] || {}\n              return (\n                <div className=\"yt-channel prtclk\" onClick={handleChClick} key={i}\n                  data-state={chid==\"\"?0:(chid==item?1:2)} data-id={item}>\n                  <Image src={channel.pfp} dir=\"asset/youtube/pfp\" w={48}/>\n                  <div className=\"txt-ovf ch-name\">{channel.name}</div>\n                </div>\n              )\n            })}\n          </div>\n        </div>\n        <div className=\"ch-text-all\">ALL</div>\n      </div>\n      <div className=\"yt-sub-vids\">\n        {ydata.vids && Object.keys(ydata.vids).sort((ka,kb)=>{\n          return new Date(ydata.vids[ka].upload) < new Date(ydata.vids[kb].upload)?1:-1\n        }).map((key, i)=>{\n          var vid = ydata.vids[key],\n              channel = ydata.channels[vid.channel] || {}\n\n          return ydata.subd.includes(channel.id) && (\n            chid==\"\" || chid==channel.id ) && (\n            <div className=\"yt-item-container prtclk\" onClick={dispatchAction}\n                  data-action=\"youtube/watchVideo\" data-payload={vid.id} key={i}>\n              <div className=\"yt-vid-thumbnail\">\n                <Image src={vid.thumb} dir=\"asset/youtube/thumbs\"/>\n              </div>\n              <div className=\"yt-vid-info\">\n                <Image src={channel.pfp} dir=\"asset/youtube/pfp\" w={36}/>\n                <div className=\"flex-grow pl-2\">\n                  <div className=\"txt-ovf yt-vid-title\">{vid.title}</div>\n                  <div className=\"yt-vid-extra\">\n                    {channel.name} • {vid.views.quantf()} views • {new Date(vid.upload).minifyDate()}\n                  </div>\n                </div>\n              </div>\n            </div>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n\nexport const LibPage = (props)=>{\n  const ydata = useSelector(state => state.youtube)\n\n  return (\n    <div className=\"yt-page\">\n      <div className=\"yt-his-container\">\n        <div className=\"yt-his-title\">\n          <span>History</span>\n          <span className=\"ch-text-all\">VIEW ALL</span>\n        </div>\n        <div className=\"yt-his-vids noscroll\">\n          <div className=\"yt-his-scbody\">\n            {ydata.library && ydata.library.hist.map((key, i)=>{\n              var vid = ydata.vids[key],\n                  channel = ydata.channels[vid.channel] || {}\n\n              return (\n                <div className=\"yt-his-vid prtclk\" onClick={dispatchAction}\n                  data-action=\"youtube/watchVideo\" data-payload={vid.id} key={i}>\n                  <Image src={vid.thumb} dir=\"asset/youtube/thumbs\"/>\n                  <div className=\"txt-ovf his-vid-title\">{vid.title}</div>\n                  <div className=\"his-chname\">{channel.name}</div>\n                </div>\n              )\n            })}\n          </div>\n        </div>\n      </div>\n      <hr className=\"my-2\"/>\n      <div className=\"flex flex-col yt-lib-cont\">\n        <div className=\"flex px-4 py-3 items-center\">\n          <Icon className=\"yt-lib-icon\" mui=\"Download\" w={20}/>\n          <div className=\"yt-dock-name text-sm ml-4\">Downloads</div>\n        </div>\n        <div className=\"flex px-4 py-3 items-center\">\n          <Icon className=\"yt-lib-icon\" mui=\"Theaters\" w={20} out/>\n          <div className=\"yt-dock-name text-sm ml-4\">Your Movies</div>\n        </div>\n        <div className=\"flex px-4 py-3 items-center\">\n          <Icon className=\"yt-lib-icon\" mui=\"AccessTime\" w={20} out/>\n          <div className=\"yt-dock-name text-sm ml-4\">Watch Later</div>\n        </div>\n        <div className=\"flex px-4 py-3 items-center\">\n          <Icon className=\"yt-lib-icon\" mui=\"ThumbUp\" w={20} out/>\n          <div className=\"yt-dock-name text-sm ml-4\">Liked Videos</div>\n        </div>\n      </div>\n      <hr className=\"my-4\"/>\n    </div>\n  )\n}\n\nexport const Home = (props)=>{\n  const ydata = useSelector(state => state.youtube)\n\n  return (\n    <div className=\"yt-page yt-feed\">\n      {ydata.home && ydata.home.map((item,i)=>{\n        var vid = ydata.vids[ydata.home[i%ydata.home.length]],\n            channel = ydata.channels[vid.channel] || {}\n\n        return (\n          <div className=\"yt-item-container prtclk\" onClick={dispatchAction}\n            data-action=\"youtube/watchVideo\" data-payload={vid.id} key={i}>\n            <div className=\"yt-vid-thumbnail\">\n              <Image src={vid.thumb} dir=\"asset/youtube/thumbs\"/>\n            </div>\n            <div className=\"yt-vid-info\">\n              <Image src={channel.pfp} dir=\"asset/youtube/pfp\" w={36}/>\n              <div className=\"flex-grow pl-2\">\n                <div className=\"txt-ovf yt-vid-title\">{vid.title}</div>\n                <div className=\"yt-vid-extra\">\n                  {channel.name} • {vid.views.quantf()} views • {new Date(vid.upload).minifyDate()}\n                </div>\n              </div>\n            </div>\n          </div>\n        )\n      })}\n    </div>\n  )\n}\n"
  },
  {
    "path": "src/containers/apps/youtube/extra.scss",
    "content": ".yt-vid-view {\n  position: absolute;\n  width: 100%;\n  height: 100%;\n  max-height: 100%;\n  bottom: 0;\n  background: var(--app-bg);\n  transition: max-height 200ms ease-in-out;\n\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n}\n\n.mini-yt-vid {\n  bottom: 56px;\n  max-height: 120px;\n  height: auto;\n  flex-direction: row;\n\n  .yt-vid-box {\n    width: 25%;\n    height: 3.2em;\n    overflow: hidden;\n  }\n\n  .yt-watch-container {\n    width: 75%;\n    flex-direction: row;\n    justify-content: space-between;\n\n    & > div{\n      width: auto;\n    }\n\n    .yt-vid-info {\n      padding: 0.5em;\n\n      .vid-title {\n        font-size: 0.8em;\n        -webkit-line-clamp: 1;\n      }\n    }\n  }\n}\n\n.yt-vid-box {\n  width: 100%;\n  height: 14em;\n  background: #343434;\n\n  .vidCont{\n    width: 100%;\n    height: 100%;\n  }\n}\n\n.yt-watch-container {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  width: 100%;\n  height: 50%;\n  flex-grow: 1;\n  overflow-y: scroll;\n\n  & > div{\n    width: 100%;\n  }\n\n  .yt-vid-info {\n    padding: 0.5em 0.8em;\n\n    .vid-title {\n      font-size: 0.92em;\n      -webkit-line-clamp: 2;\n    }\n\n    .vid-stat {\n      font-weight: 500;\n      color: var(--light-txt);\n      font-size: 0.72em;\n    }\n\n    .vid-acts {\n      display: flex;\n      justify-content: space-around;\n      font-size: 0.75em;\n      color: var(--med-txt);\n      margin: 1em 0;\n    }\n  }\n\n  .yt-mini-ctrl{\n    display: flex;\n    padding: 0 4px;\n    color: var(--med-txt);\n  }\n\n  .yt-channel-row {\n    display: flex;\n    align-items: center;\n    position: relative;\n    justify-content: space-between;\n    border: solid 0 #ddd;\n    border-width: 1px 0;\n\n    .imageCont {\n      padding: 0.5em;\n      overflow: hidden;\n\n      img {\n        border-radius: 50%;\n      }\n    }\n\n    .text-xss {\n      font-weight: 500;\n    }\n\n    .subscribed-container {\n      display: flex;\n      align-items: center;\n      padding: 0 1em;\n    }\n\n    .red-txt {\n      color: #df0404;\n    }\n  }\n\n  .yt-comment-box{\n    padding: 0.5em 1em;\n  }\n}\n"
  },
  {
    "path": "src/containers/apps/youtube/index.js",
    "content": "import React, {useState, useEffect} from 'react';\nimport {useSelector, useDispatch} from 'react-redux';\n\nimport {Icon, Image, LazyComponent} from 'components/utils';\nimport {dispatchAction, dispatchAct} from 'store/actions';\nimport {Home, ViewPage, TrendingPage, SubsPage, LibPage} from './extra';\nimport './youtube.scss';\n\nexport const YoutubeApp = () => {\n  const app = useSelector(state => state.home.apps.youtube || {})\n  const home = useSelector(state => state.home)\n  const show = home.ishome==false && home.stack.at(-1)==app.payload\n  const pagetree = app && app.pagetree || {\n    \"main\": {\n      \"home\" : {},\n      \"subs\" : {},\n      \"lib\" : {}\n    }\n  }\n\n  useEffect(()=>{\n    if(app && !app.pagetree){\n      dispatchAct({type: \"home/setApp\", payload: {\n        id: app.payload,\n        data: {\n          ... app,\n          pagetree: pagetree,\n          path: ['main']\n        }\n      }})\n    }\n  }, [app])\n\n  return <AppContainer app={app} show={show}/>\n}\n\nconst AppContainer = ({app, show}) => {\n  const ydata = useSelector(state => state.youtube)\n  const [tab, setTab] = useState(0)\n  const clstring = `${app.payload}-wrapper`\n\n  const changeTab = (e)=>{\n    if(e.target.dataset.payload) setTab(e.target.dataset.payload)\n  }\n\n  return (\n    <div className={\"app-wrapper \"+clstring} id={clstring} data-open={show}>\n      <div className=\"app-inner-wrapper yt-inner-wrapper\">\n        <div className=\"youtube-home\">\n          <div className=\"yt-top-nav\">\n            <Image src=\"asset/youtube/namelogo\" w={80}/>\n            <div className=\"y-nav-icons\">\n              <Icon mui=\"Cast\" w={18}/>\n              <Icon mui=\"NotificationsNone\" round w={22}/>\n              <Icon mui=\"Search\" w={22}/>\n              <Image className=\"rounded rounded-full\" src=\"blue.jpg\" w={22}/>\n            </div>\n          </div>\n          {tab == 0 && <Home/>}\n          {tab == 1 && <TrendingPage/>}\n          {tab == 3 && <SubsPage/>}\n          {tab == 4 && <LibPage/>}\n          {<ViewPage/>}\n          <div className=\"yt-bottom-nav\" data-hide={ydata.comp}>\n            <Icon className=\"active-dark-lit\" mui=\"Home\" w={24} label=\"Home\"\n                  out={tab!=0} onClick={changeTab} payload={0}/>\n            <Icon className=\"active-dark-lit\" mui=\"Explore\" w={24} label=\"Explore\"\n                  out={tab!=1} onClick={changeTab} payload={1}/>\n            <Icon mui=\"AddCircleOutline\" w={36} round/>\n            <Icon className=\"active-dark-lit\" mui=\"Subscriptions\" w={24} label=\"Subscriptions\"\n                  out={tab!=3} onClick={changeTab} payload={3}/>\n            <Icon className=\"active-dark-lit\" mui=\"VideoLibrary\" w={24} label=\"Library\"\n                  out={tab!=4} onClick={changeTab} payload={4}/>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "src/containers/apps/youtube/youtube.scss",
    "content": ".youtube-home {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  height: 100%;\n}\n\n.yt-bottom-nav,\n.yt-top-nav {\n  width: 100%;\n  display: flex;\n  position: relative;\n  justify-content: space-between;\n  padding: 0.5em 0.6em;\n  color: var(--txt-col);\n\n  .y-nav-icons {\n    display: flex;\n\n    .imageCont,\n    .uicon {\n      margin: 0 0.5em;\n    }\n  }\n}\n\n.yt-bottom-nav {\n  padding: 0.5em;\n  color: var(--med-txt);\n  align-items: center;\n  display: grid;\n  grid-template-columns: repeat(5, 1fr);\n  transition: transform 200ms ease-in-out;\n\n  &[data-hide=\"true\"]{\n    transform: translateY(60px);\n    pointer-events: none;\n  }\n\n  .uicon {\n    font-size: 0.7em;\n  }\n}\n\n.yt-page {\n  width: 100%;\n  flex-grow: 1;\n  overflow-y: scroll;\n}\n\n.yt-item-container {\n  margin-bottom: 0.5em;\n\n  .yt-vid-thumbnail {\n    min-height: 12em;\n    background: var(--comp-txt);\n  }\n\n  .yt-vid-info {\n    display: flex;\n    width: 100%;\n    margin-top: 0.5em;\n    margin-bottom: 1em;\n    padding: 0 0.5em;\n\n    .imageCont {\n      min-width: 36px;\n\n      img {\n        border-radius: 2em;\n      }\n    }\n\n    .yt-vid-title {\n      font-size: 0.84em;\n      font-weight: 600;\n      overflow: hidden;\n      display: -webkit-box;\n      -webkit-line-clamp: 1;\n      -webkit-box-orient: vertical;\n      text-overflow: ellipsis;\n    }\n\n    .yt-vid-extra {\n      font-size: 0.64em;\n      font-weight: 500;\n      color: var(--sat-txt);\n    }\n  }\n}\n\n.yt-trending-page {}\n\n.yt-trending-catg {\n  display: grid;\n  grid-template-columns: repeat(2, auto);\n  grid-row-gap: 0.5em;\n  grid-column-gap: 0.5em;\n  padding: 1em;\n\n  .yt-catg {\n    display: flex;\n    padding: 0.5em;\n    color: var(--white);\n    font-size: 0.9em;\n    font-weight: 500;\n    border-radius: 6px;\n\n    img {\n      filter: saturate(0) brightness(3);\n      margin-left: 0.25em;\n      margin-right: 0.5em;\n    }\n\n    &:nth-child(1) {\n      background: rgb(195,9,9);\n      background: linear-gradient(135deg, rgba(195,9,9,1) 0%, rgba(235,59,59,1) 100%);\n    }\n\n    &:nth-child(2) {\n      background: rgb(9,195,83);\n      background: linear-gradient(135deg, rgba(21, 143, 69, 1) 0%, rgba(59,235,141,1) 100%);\n    }\n\n    &:nth-child(3) {\n      background: rgb(235,176,93);\n      background: linear-gradient(135deg, rgba(186, 142, 79, 1) 0%, rgba(240,207,180,1) 100%);\n    }\n\n    &:nth-child(4) {\n      background: rgb(59,65,226);\n      background: linear-gradient(135deg, rgba(59,65,226,1) 0%, rgba(180,196,240,1) 100%);\n    }\n\n    &:nth-child(5) {\n      background: rgb(163,163,163);\n      background: linear-gradient(135deg, rgba(103, 101, 101, 1) 0%, rgba(218,221,198,1) 100%);\n    }\n\n    &:nth-child(6) {\n      background: rgb(29,210,71);\n      background: linear-gradient(135deg, rgba(33, 167, 64, 1) 0%, rgba(106,208,121,1) 100%);\n\n      & img {\n        filter: saturate(0) invert(1) brightness(3);\n      }\n    }\n  }\n}\n\n.ch-text-all {\n  padding-left: 1em;\n  padding-right: 0.5em;\n  font-size: 0.8em;\n  color: #125dc2;\n}\n\n.yt-subs-container {\n  display: flex;\n  align-items: center;\n  padding: 0 0.25em;\n  margin-bottom: 0.5em;\n\n  .yt-channels-sc {\n    flex-grow: 1;\n    overflow-x: scroll;\n\n    .yt-ch-body {\n      display: flex;\n      width: max-content;\n    }\n  }\n\n  .yt-channel {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    padding: 0.5em 0.5em 0.25em;\n    box-sizing: border-box;\n\n    &[data-state=\"1\"] {\n      background: rgba(74, 124, 224, 0.5);\n    }\n\n    &[data-state=\"2\"] {\n      opacity: 0.25;\n    }\n\n    .ch-name {\n      max-width: 48px;\n      font-size: 0.64em;\n      text-align: center;\n    }\n\n    .imageCont {\n      border-radius: 2em;\n      overflow: hidden;\n    }\n  }\n}\n\n.yt-his-container {\n  margin-top: 0.5em;\n\n  .yt-his-title {\n    padding: 0.25em 0.5em;\n    display: flex;\n    justify-content: space-between;\n  }\n\n  .yt-his-vids {\n    width: 100%;\n    overflow-x: scroll;\n  }\n\n  .yt-his-scbody {\n    width: max-content;\n    display: flex;\n  }\n\n  .yt-his-vid {\n    width: 8em;\n    margin: 0 0.5em;\n\n    .his-vid-title {\n      max-height: 48px;\n      -webkit-line-clamp: 2;\n      font-size: 0.72em;\n    }\n\n    .his-chname {\n      color: var(--med-txt);\n      font-weight: 400;\n      font-size: 0.64em;\n    }\n  }\n}\n\n.yt-lib-cont {\n  color: var(--med-txt);\n  .yt-lib-icon svg{\n    fill: var(--med-txt);\n  }\n}\n"
  },
  {
    "path": "src/containers/home/home.scss",
    "content": ".viewport {\n  position: absolute;\n  width: 100%;\n  height: 100%;\n  top: 0;\n  overflow: hidden;\n  display: flex;\n  flex-direction: column;\n  z-index: 0;\n}\n\n.home {\n  width: 100%;\n  // height: 100%;\n  // font-size: 3em;\n  font-weight: 600;\n  color: #1e252b;\n  flex-grow: 1;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  position: relative;\n  // padding: 0 1.6em;\n  .homescreen-container {\n    width: 100%;\n    height: 100%;\n    position: relative;\n    flex-grow: 1;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n  }\n}\n\n.favorite-bar {\n  width: 100%;\n  // height: 2em;\n  padding: 0 0.5em 0.6em;\n  display: flex;\n  justify-content: space-around;\n}\n\n.homescreen {\n  position: absolute;\n  inset: 0;\n\n  .pages-container {\n    height: 100%;\n    display: flex;\n    flex-direction: column;\n  }\n}\n\n.pages-container {\n  .slick-list {\n    flex-grow: 1;\n  }\n\n  .slick-track {\n    height: 100%;\n  }\n\n  .slick-slide > div {\n    height: 100%;\n  }\n\n  .page-container {\n    width: 100%;\n    height: 100%;\n    display: flex !important;\n    // place-items: center;\n    flex-direction: column;\n    align-items: center;\n    padding: 0.5em;\n    padding-bottom: 0;\n  }\n\n  .slick-dots {\n    position: relative;\n    bottom: 0;\n\n    li {\n      width: 6px;\n    }\n  }\n}\n\n.grid-page {\n  width: 100%;\n  max-height: 100%;\n  flex-grow: 1;\n  display: grid;\n  grid-template-columns: repeat(4, 1fr);\n  grid-template-rows: repeat(6, 1fr);\n  // grid-template-rows: repeat(6, auto);\n\n  .page-cell {\n    box-sizing: border-box;\n    border: solid 1px red;\n  }\n}\n\n.cell-container {\n  display: grid;\n  position: relative;\n  place-items: center;\n  align-items: center;\n\n  .app-container{\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n  }\n\n  .app-name {\n    font-size: 0.8em;\n    color: var(--med-txt);\n    font-weight: 600;\n    margin: 4px 0;\n  }\n}\n\n.uicon[data-padd=\"true\"] {\n  background: #fefefe;\n\n  & > * {\n    transform: scale(0.75);\n  }\n}\n\n.apps-wrapper, .recent-apps-container{\n  position: absolute;\n  inset: 0;\n}\n\n.full-height-swiper{\n  height: 100%;\n\n  .slick-list, .slick-track{\n    height: 100%;\n  }\n\n  .slick-slide > div{\n    height: 100%;\n  }\n}\n\n.recent-apps-container{\n  opacity: 0;\n  transition: opacity 200ms ease-in-out;\n  pointer-events: none;\n\n  &[data-hide=\"false\"]{\n    pointer-events: auto;\n    opacity: 1;\n  }\n}\n\n.recent-slider{\n  height: 100%;\n  transform: scale(1);\n  box-sizing: border-box;\n  transition: transform 200ms ease-in-out;\n\n  &[data-hide=\"false\"]{\n    transform: scale(0.58);\n  }\n\n  .slick-list {\n    margin: 0 -1.5em;\n    overflow: visible;\n  }\n\n  .slick-slide > div {\n    margin: 0 1.5em;\n  }\n}\n\n.mini-app-container{\n  background: #444;\n  height: 100%;\n  border-radius: 2em;\n  // overflow: hidden;\n  position: relative;\n  opacity: 1;\n  transform: translateY(0);\n  transition-property: opacity, transform;\n\n  &[data-rem=\"true\"]{\n    animation: fade-up 600ms ease-in-out;\n  }\n}\n\n.closing-all-apps .mini-app-container{\n  animation: fade-up 600ms ease-in-out;\n}\n\n@keyframes fade-up {\n  0%{\n    opacity: 1;\n    transform: translateY(0);\n  }\n\n  33%{\n    opacity: 0;\n    transform: translateY(-50%);\n  }\n\n  100%{\n    opacity: 0;\n    transform: translateY(-50%);\n  }\n}\n\n.mini-app-icon{\n  width: 100%;\n  position: absolute;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  transform: translateY(-50%);\n  z-index: 1;\n\n  .uicon{\n    width: 20%;\n    border-radius: 40%;\n    // width: max-content;\n  }\n}\n\n.close-recent-container{\n  width: 100%;\n  height: 20%;\n  position: absolute;\n  bottom: 0;\n  display: grid;\n  place-items: center;\n\n  .close-all-btn{\n    padding: 0.5em 3em;\n    border-radius: 2em;\n    color: var(--comp-txt);\n    background: rgba(68, 68, 68, 0.25);\n  }\n}\n\n.no-recent-container{\n  position: absolute;\n  inset: 0;\n  display: grid;\n  place-items: center;\n  font-size: 1.2em;\n  letter-spacing: 1px;\n  word-spacing: 2px;\n  color: var(--med-txt);\n}\n\n.mini-app-holder{\n  position: relative;\n  width: 100%;\n  height: 100%;\n  border-radius: 2em;\n  overflow: hidden;\n}\n\n.mini-app-wrapper{\n  height: 100%;\n  border-radius: 0;\n}\n\n.recent-cover{\n  position: absolute;\n  inset: 0;\n  z-index: 10;\n}\n"
  },
  {
    "path": "src/containers/home/index.js",
    "content": "import React, {useState, useEffect, useRef} from 'react';\nimport {useSelector} from 'react-redux';\nimport Hammer from '@win11react/react-hammerjs';\nimport Swiper from 'react-slick';\n\nimport * as Widgets from 'components/widgets';\nimport { Icon } from 'components/utils';\nimport QuickPanel from 'components/quickpanel';\nimport StatusBar from 'components/statusbar';\nimport BottomNav from 'components/bottomnav';\nimport { dispatchAction, dispatchAct } from 'store/actions';\n\nimport * as Applications from 'containers/apps';\n\nimport './home.scss';\n\nconst apps_order = Object.keys(Applications).map(key => {\n  return key.slice(0,key.length - 3).toLowerCase()\n})\n\nfunction Home() {\n  const [action, setAction] = useState(\"Tap\");\n  const display = useSelector((state) => state.global.display);\n  const home = useSelector((state) => state.home);\n  const favbar = useSelector((state) => state.home.favbar);\n  const apps = useSelector((state) => state.home.apps);\n\n  const openedapp = !home.ishome && home.stack.at(-1);\n  const viewportclass = openedapp ? openedapp + \"-viewport\":\"\"\n\n  const handleSwipe = (e)=>{\n    setAction(e.type + \" \" + e.direction)\n    if(e.direction === 16){\n      dispatchAct({type: \"quickpanel/open\"});\n    }\n\n    if(process.env.REACT_APP_ENV!=\"development\"){\n      if (navigator.userAgentData){\n        document.documentElement.requestFullscreen();\n      }\n    }\n  }\n\n  useEffect(()=>{\n    if(apps && apps[apps_order[0]] && !apps[apps_order[0]].payload){\n      var tmp = {...apps}\n      apps_order.map(x=>{\n        tmp[x] = {...apps[x]}\n        tmp[x].payload = x\n      })\n\n      dispatchAct({type: \"home/setApps\",payload: tmp})\n    }\n  }, [apps])\n\n  return (\n    <div className={\"viewport \" + viewportclass}>\n      <StatusBar bg={openedapp && \"var(--statusbg)\"} invert={home.ishome?false:null}/>\n      <QuickPanel/>\n      <div className='home'>\n        <Hammer onSwipe={handleSwipe} direction='DIRECTION_ALL'>\n          <div className=\"homescreen-container\">\n            <HomeScreen/>\n          </div>\n        </Hammer>\n        <div className=\"favorite-bar\">\n          {favbar.map((favicon, i)=>{\n            var app = apps[favicon]\n            return (\n              <Icon className=\"mdShad press-in\" src={\"apps/\" + app.icon} key={i}\n                action={app.action || \"home/openApp\"} w={52} h={52}\n                radii={20} data-padd={app.padd} payload={app.payload}/>\n            )\n          })}\n        </div>\n        <AppWrapper openedapp={openedapp}/>\n        <RecentWrapper/>\n      </div>\n      <BottomNav bg={openedapp && \"var(--navbg)\"} invert={home.ishome?false:null}/>\n    </div>\n  )\n}\n\nconst AppWrapper = ({openedapp})=>{\n  const home = useSelector((state) => state.home);\n  const stack = useSelector((state) => state.home.stack);\n  const opened_apps = apps_order.filter(x => stack.includes(x));\n  const appScroll = useRef();\n\n  useEffect(()=>{\n    if(stack.length){\n      if(appScroll.current){\n        var appidx = opened_apps.indexOf(openedapp)\n        appScroll.current.slickGoTo(appidx, true)\n      }\n    }\n  }, [stack])\n\n  return (\n    <div className=\"apps-wrapper\" data-ninja=\"true\">\n      <Swiper className=\"full-app-container full-height-swiper\" {...{\n        dots: false,\n        arrows: false,\n        infinite: false,\n        swipe: false,\n        speed: 200\n      }} ref={appScroll}>\n      {opened_apps.map(item=>{\n        var key = item.capitalize()+\"App\",\n            WinApp = Applications[key];\n\n        return <WinApp key={item}/>\n      })}\n      </Swiper>\n    </div>\n  )\n}\n\nconst MiniApp = ({app, handleSwipeUp})=>{\n  const miniRef = useRef();\n\n  useEffect(()=>{\n    var cloneApp = document.getElementById(app.payload+\"-wrapper\");\n    if(cloneApp){\n      cloneApp = cloneApp.cloneNode(true);\n      cloneApp.removeAttribute('id');\n      cloneApp.removeAttribute('data-open');\n      cloneApp.classList.toggle('app-wrapper');\n      cloneApp.classList.toggle('mini-app-wrapper');\n\n      var parentDiv = miniRef.current;\n      parentDiv.innerHTML = \"\";\n      parentDiv.appendChild(cloneApp);\n    }\n  }, [app.payload])\n\n  return (\n    <Hammer onSwipeUp={handleSwipeUp} direction=\"DIRECTION_ALL\">\n      <div className=\"mini-app-container\" data-rem=\"false\">\n        <div className=\"mini-app-icon\">\n          <Icon src={\"apps/\" + app.icon} data-padd={app.padd}/>\n        </div>\n        <div className=\"mini-app-holder\" ref={miniRef}></div>\n        <div className=\"recent-cover\" onClick={dispatchAction}\n          data-action=\"home/openApp\" data-payload={app.payload}></div>\n      </div>\n    </Hammer>\n  )\n}\n\nconst RecentWrapper = ()=>{\n  const home = useSelector((state) => state.home);\n  const apps = useSelector(state => state.home.apps);\n  const [recent_lag, setLag] = useState(home.recent);\n  const recentScroll = useRef();\n  const recentContainer = useRef();\n  var recents = [...home.stack];\n\n  const closeRecent = (e) => {\n    if (e.target.classList.contains(\"recent-apps-container\") || home.stack.length==0) {\n      dispatchAct({ type: \"home/closeRecent\" });\n    }\n  }\n\n  const closeAll = (e)=>{\n    if(recentContainer.current){\n      recentContainer.current.classList.toggle('closing-all-apps')\n      setTimeout(()=>{\n        recentContainer.current.classList.toggle('closing-all-apps')\n        dispatchAct({ type: \"home/closeAllApps\" });\n      }, 400)\n    }\n  }\n\n  const scrollRecentTo = (i, anim=false)=>{\n    if(recentScroll.current){\n      recentScroll.current.slickGoTo(i, anim)\n    }\n  }\n\n  const handleSwipeUp = (e)=>{\n    var payload = e.target.dataset.payload;\n    e.target.dataset.rem = true;\n\n    setTimeout(()=>{\n      var i = recents.indexOf(payload);\n      if(i!=0) scrollRecentTo(i - 1);\n      setTimeout(()=>{\n        e.target.dataset.rem = false;\n        dispatchAct({type: \"home/closeApp\", payload: payload})\n      }, 200)\n    },200)\n  }\n\n  useEffect(()=>{\n    if(home.stack.length && home.recent){\n      scrollRecentTo(home.stack.length - 1, true)\n    }\n\n    if(home.recent) setLag(true)\n    else {\n      setTimeout(()=>{\n        setLag(false)\n      }, 600)\n    }\n  }, [home.recent])\n\n  return (\n    <div className=\"recent-apps-container backblur\" onClick={closeRecent} data-hide={!home.recent}>\n      <div className=\"recent-slider\" data-hide={!home.recent} ref={recentContainer}>\n        <Swiper className=\"recent-app-container full-height-swiper\" {...{\n          dots: false,\n          arrows: false,\n          infinite: false,\n          initialSlide: home.stack.length,\n          speed: 200\n        }} ref={recentScroll}>\n        {recent_lag && home.stack.map((item,idx) => {\n          var app = apps[item]\n          return <MiniApp app={app || {}} handleSwipeUp={handleSwipeUp} key={item}/>\n        })}\n        </Swiper>\n      </div>\n      {home.stack.length==0?(\n        <div className=\"no-recent-container\">\n          No recent tasks\n        </div>\n      ):null}\n      <div className=\"close-recent-container\">\n        <div className=\"close-all-btn press-in quick-trans\" onClick={closeAll}>Close all</div>\n      </div>\n    </div>\n  )\n}\n\nconst HomeScreen = (props)=>{\n  const home = useSelector(state => state.home)\n  const apps = useSelector(state => state.home.apps)\n  const pages = useSelector(state => state.home.slides.list)\n  const settings = {\n    dots: true,\n    arrows: false,\n    infinite: false,\n    initialSlide: 0,\n    speed: 200\n  }\n\n  return (\n    <div className=\"homescreen\">\n      <Swiper className=\"pages-container\" {...settings}>\n        {home && [...Array(home.slides.count)].map((x,i)=>{\n          return (\n            <div className=\"page-container\" key={i}>\n              <div className=\"grid-page\">\n                {Object.keys(pages).map((id, ix)=>{\n                  var item = pages[id]\n                  if(item.page != i+1) return null\n\n                  if(item.type==\"app\"){\n                    var app = apps[id]\n                    return (\n                      <div className=\"cell-container\" key={ix} style={{\n                        gridRow: item.row.join(\" / \"),\n                        gridColumn: item.col.join(\" / \")\n                      }}>\n                        <div className=\"app-container\">\n                          <Icon className=\"press-in\" src={\"apps/\" + app.icon}\n                            action={app.action || \"home/openApp\"} w={52} h={52}\n                            radii={22} data-padd={app.padd} payload={app.payload}/>\n                          <div className=\"app-name\">{app.name}</div>\n                        </div>\n                      </div>\n                    )\n                  }else if (item.type==\"widget\") {\n                    var Widget = Widgets[item.widget]\n                    return (\n                      <div className=\"cell-container\" key={ix} style={{\n                        gridRow: item.row.join(\" / \"),\n                        gridColumn: item.col.join(\" / \")\n                      }}>\n                        <Widget/>\n                      </div>\n                    )\n                  }\n                })}\n              </div>\n            </div>\n          )\n        })}\n      </Swiper>\n    </div>\n  )\n}\n\nexport default Home;\n"
  },
  {
    "path": "src/index.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');\n\n@font-face {\n  font-family: \"SamsungOne400\";\n  src: url(\"https://d3unf4s5rp9dfh.cloudfront.net/ONEUI/SamsungOneKorean-400.woff2\")\n      format(\"woff2\"),\n    url(https://d3unf4s5rp9dfh.cloudfront.net/ONEUI/SamsungOneKorean-400.woff)\n      format(\"woff\");\n  font-weight: 400;\n}\n\n@font-face {\n  font-family: \"SamsungOne500\";\n  src: url(\"https://d3unf4s5rp9dfh.cloudfront.net/ONEUI/SamsungOneKorean-500.woff2\")\n      format(\"woff2\"),\n    url(https://d3unf4s5rp9dfh.cloudfront.net/ONEUI/SamsungOneKorean-500.woff)\n      format(\"woff\");\n  font-weight: 500;\n}\n\n@font-face {\n  font-family: \"SamsungOne700\";\n  src: url(\"https://d3unf4s5rp9dfh.cloudfront.net/ONEUI/SamsungOneKorean-700.woff2\")\n      format(\"woff2\"),\n    url(https://d3unf4s5rp9dfh.cloudfront.net/ONEUI/SamsungOneKorean-700.woff)\n      format(\"woff\");\n  font-weight: 700;\n}\n\nhtml, body{\n  margin: 0;\n  padding: 0;\n  height: 100%;\n}\n\nbody {\n  font-family: \"SamsungOne500\", sans-serif;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  /* font-family: \"SamsungOne500-kr\",-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", */\n    /* \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", */\n    /* sans-serif; */\n\n  background: #121212;\n  /* color: #fefefe; */\n  user-select: none;\n  overflow: hidden;\n}\n\n* {\n  scrollbar-width: none;\n}\n\n*::selection {\n  /* background: initial; */\n}\n\ncode {\n  font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n    monospace;\n}\n\n#root{\n  width: 100%;\n  height: 100%;\n  display: grid;\n  place-items: center;\n}\n\n.App {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  max-width: 440px;\n  max-height: 100vh;\n}\n\n.appwrap {\n  position: relative;\n  height: 100%;\n  z-index: 0;\n  overflow: hidden;\n}\n\n.redbd{\n  box-sizing: border-box;\n  border: solid 1px red;\n}\n\n.dpShad {\n  filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.25));\n}\n\n.mdShad {\n  filter: drop-shadow(0 1px 4px rgba(41, 41, 41, 0.2));\n}\n\n.ltShad {\n  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25));\n}\n\n*::-webkit-scrollbar {\n  width: 4px;\n  height: 4px;\n  background-color: transparent;\n}\n\n*:hover::-webkit-scrollbar-thumb{\n  background: rgba(32, 24, 148, 0.4);\n}\n\n*::-webkit-scrollbar-thumb {\n  width: 4px;\n  height: 4px;\n  border-radius: 10px;\n  background-color: transparent;\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport store from './store';\nimport * as Sentry from \"@sentry/react\";\nimport { BrowserTracing } from \"@sentry/tracing\";\nimport { Provider } from 'react-redux';\nimport * as serviceWorkerRegistration from './serviceWorkerRegistration';\n\nSentry.init({\n  dsn: \"https://202b09d8695844e89470727c1c381957@o575799.ingest.sentry.io/6385094\",\n  integrations: [new BrowserTracing()],\n\n  // Set tracesSampleRate to 1.0 to capture 100%\n  // of transactions for performance monitoring.\n  // We recommend adjusting this value in production\n  tracesSampleRate: 1.0,\n});\n\nReactDOM.render(\n  <React.StrictMode>\n    <Provider store={store}>\n      <App />\n    </Provider>\n  </React.StrictMode>,\n  document.getElementById('root')\n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorkerRegistration.register();\n"
  },
  {
    "path": "src/service-worker.js",
    "content": "/* eslint-disable no-restricted-globals */\n\n// This service worker can be customized!\n// See https://developers.google.com/web/tools/workbox/modules\n// for the list of available Workbox modules, or add any other\n// code you'd like.\n// You can also remove this file if you'd prefer not to use a\n// service worker, and the Workbox build step will be skipped.\n\nimport { clientsClaim } from 'workbox-core';\nimport { ExpirationPlugin } from 'workbox-expiration';\nimport { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';\nimport { registerRoute } from 'workbox-routing';\nimport { StaleWhileRevalidate } from 'workbox-strategies';\n\nclientsClaim();\n\n// Precache all of the assets generated by your build process.\n// Their URLs are injected into the manifest variable below.\n// This variable must be present somewhere in your service worker file,\n// even if you decide not to use precaching. See https://cra.link/PWA\nprecacheAndRoute(self.__WB_MANIFEST);\n\n// Set up App Shell-style routing, so that all navigation requests\n// are fulfilled with your index.html shell. Learn more at\n// https://developers.google.com/web/fundamentals/architecture/app-shell\nconst fileExtensionRegexp = new RegExp('/[^/?]+\\\\.[^/]+$');\nregisterRoute(\n  // Return false to exempt requests from being fulfilled by index.html.\n  ({ request, url }) => {\n    // If this isn't a navigation, skip.\n    if (request.mode !== 'navigate') {\n      return false;\n    } // If this is a URL that starts with /_, skip.\n\n    if (url.pathname.startsWith('/_')) {\n      return false;\n    } // If this looks like a URL for a resource, because it contains // a file extension, skip.\n\n    if (url.pathname.match(fileExtensionRegexp)) {\n      return false;\n    } // Return true to signal that we want to use the handler.\n\n    return true;\n  },\n  createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')\n);\n\n// An example runtime caching route for requests that aren't handled by the\n// precache, in this case same-origin .png requests like those from in public/\nregisterRoute(\n  // Add in any other file extensions or routing criteria as needed.\n  ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.\n  new StaleWhileRevalidate({\n    cacheName: 'images',\n    plugins: [\n      // Ensure that once this runtime cache reaches a maximum size the\n      // least-recently used images are removed.\n      new ExpirationPlugin({ maxEntries: 50 }),\n    ],\n  })\n);\n\n// This allows the web app to trigger skipWaiting via\n// registration.waiting.postMessage({type: 'SKIP_WAITING'})\nself.addEventListener('message', (event) => {\n  if (event.data && event.data.type === 'SKIP_WAITING') {\n    self.skipWaiting();\n  }\n});\n\n// Any other custom service worker logic can go here.\n"
  },
  {
    "path": "src/serviceWorkerRegistration.js",
    "content": "// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://cra.link/PWA\n\nconst isLocalhost = Boolean(\n  window.location.hostname === 'localhost' ||\n    // [::1] is the IPv6 localhost address.\n    window.location.hostname === '[::1]' ||\n    // 127.0.0.0/8 are considered localhost for IPv4.\n    window.location.hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)\n);\n\nexport function register(config) {\n  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n    // The URL constructor is available in all browsers that support SW.\n    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n    if (publicUrl.origin !== window.location.origin) {\n      // Our service worker won't work if PUBLIC_URL is on a different origin\n      // from what our page is served on. This might happen if a CDN is used to\n      // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n      return;\n    }\n\n    window.addEventListener('load', () => {\n      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n      if (isLocalhost) {\n        // This is running on localhost. Let's check if a service worker still exists or not.\n        checkValidServiceWorker(swUrl, config);\n\n        // Add some additional logging to localhost, pointing developers to the\n        // service worker/PWA documentation.\n        navigator.serviceWorker.ready.then(() => {\n          console.log(\n            'This web app is being served cache-first by a service ' +\n              'worker. To learn more, visit https://cra.link/PWA'\n          );\n        });\n      } else {\n        // Is not localhost. Just register service worker\n        registerValidSW(swUrl, config);\n      }\n    });\n  }\n}\n\nfunction registerValidSW(swUrl, config) {\n  navigator.serviceWorker\n    .register(swUrl)\n    .then((registration) => {\n      registration.onupdatefound = () => {\n        const installingWorker = registration.installing;\n        if (installingWorker == null) {\n          return;\n        }\n        installingWorker.onstatechange = () => {\n          if (installingWorker.state === 'installed') {\n            if (navigator.serviceWorker.controller) {\n              // At this point, the updated precached content has been fetched,\n              // but the previous service worker will still serve the older\n              // content until all client tabs are closed.\n              console.log(\n                'New content is available and will be used when all ' +\n                  'tabs for this page are closed. See https://cra.link/PWA.'\n              );\n\n              // Execute callback\n              if (config && config.onUpdate) {\n                config.onUpdate(registration);\n              }\n            } else {\n              // At this point, everything has been precached.\n              // It's the perfect time to display a\n              // \"Content is cached for offline use.\" message.\n              console.log('Content is cached for offline use.');\n\n              // Execute callback\n              if (config && config.onSuccess) {\n                config.onSuccess(registration);\n              }\n            }\n          }\n        };\n      };\n    })\n    .catch((error) => {\n      console.error('Error during service worker registration:', error);\n    });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n  // Check if the service worker can be found. If it can't reload the page.\n  fetch(swUrl, {\n    headers: { 'Service-Worker': 'script' },\n  })\n    .then((response) => {\n      // Ensure service worker exists, and that we really are getting a JS file.\n      const contentType = response.headers.get('content-type');\n      if (\n        response.status === 404 ||\n        (contentType != null && contentType.indexOf('javascript') === -1)\n      ) {\n        // No service worker found. Probably a different app. Reload the page.\n        navigator.serviceWorker.ready.then((registration) => {\n          registration.unregister().then(() => {\n            window.location.reload();\n          });\n        });\n      } else {\n        // Service worker found. Proceed as normal.\n        registerValidSW(swUrl, config);\n      }\n    })\n    .catch(() => {\n      console.log('No internet connection found. App is running in offline mode.');\n    });\n}\n\nexport function unregister() {\n  if ('serviceWorker' in navigator) {\n    navigator.serviceWorker.ready\n      .then((registration) => {\n        registration.unregister();\n      })\n      .catch((error) => {\n        console.error(error.message);\n      });\n  }\n}\n"
  },
  {
    "path": "src/store/actions/data/apps.js",
    "content": "var apps = [\n  {\n    name: 'Assistant',\n    icon: 'assistant',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'BuyMeACoffee',\n    icon: 'buyme',\n    action: 'home/openLink',\n    payload: 'https://buymeacoffee.com/blueedgetechno',\n    type: 'app'\n  },\n  {\n    name: 'Calender',\n    icon: 'calender',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Chrome',\n    icon: 'chrome',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Classroom',\n    icon: 'classroom',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Contacts',\n    icon: 'contacts',\n    type: 'app'\n  },\n  {\n    name: 'Discord',\n    icon: 'discord',\n    type: 'app',\n    action: 'home/openLink',\n    payload: 'https://discord.gg/NcjaNdwtnR'\n  },\n  {\n    name: 'Docs',\n    icon: 'docs',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Drive',\n    icon: 'drive',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Duo',\n    icon: 'duo',\n    type: 'app'\n  },\n  {\n    name: 'Earth',\n    icon: 'earth',\n    type: 'app'\n  },\n  {\n    name: 'Forms',\n    icon: 'forms',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'GBoard',\n    icon: 'gboard',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Github',\n    icon: 'github',\n    type: 'app',\n    action: 'home/openLink',\n    payload: 'https://github.com/blueedgetechno/androidInReact',\n    padd: true\n  },\n  {\n    name: 'Gmail',\n    icon: 'gmail',\n    type: 'app',\n    action: 'home/openLink',\n    payload: 'mailto:blueedgetechno@gmail.com',\n    padd: true\n  },\n  {\n    name: 'Search',\n    icon: 'google',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Google Fit',\n    icon: 'googlefit',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'GPay',\n    icon: 'googlepay',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Keep Notes',\n    icon: 'keep',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Maps',\n    icon: 'maps',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Meet',\n    icon: 'meet',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Messages',\n    icon: 'messages',\n    type: 'app'\n  },\n  {\n    name: 'News',\n    icon: 'news',\n    type: 'app'\n  },\n  {\n    name: 'Photos',\n    icon: 'photos',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Books',\n    icon: 'playbooks',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Movies',\n    icon: 'playmovies',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Play Store',\n    icon: 'playstore',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Apps',\n    icon: 'ssapps',\n    type: 'app'\n  },\n  {\n    name: 'Settings',\n    icon: 'settings',\n    type: 'app'\n  },\n  {\n    name: 'Sheets',\n    icon: 'sheets',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Slides',\n    icon: 'slides',\n    type: 'app',\n    padd: true\n  },\n  {\n    name: 'Browser',\n    icon: 'ssbrowser',\n    type: 'app'\n  },\n  {\n    name: 'Calculator',\n    icon: 'sscalculator',\n    type: 'app'\n  },\n  {\n    name: 'Calender',\n    icon: 'sscalender',\n    type: 'app'\n  },\n  {\n    name: 'Camera',\n    icon: 'sscamera',\n    type: 'app'\n  },\n  {\n    name: 'Clock',\n    icon: 'ssclock',\n    type: 'app'\n  },\n  {\n    name: 'Contacts',\n    icon: 'sscontacts',\n    type: 'app'\n  },\n  {\n    name: 'Files',\n    icon: 'ssfiles',\n    type: 'app'\n  },\n  {\n    name: 'Gallery',\n    icon: 'ssgallery',\n    type: 'app'\n  },\n  {\n    name: 'Health',\n    icon: 'sshealth',\n    type: 'app'\n  },\n  {\n    name: 'Keyboard',\n    icon: 'sskeyboard',\n    type: 'app'\n  },\n  {\n    name: 'Mail',\n    icon: 'ssmail',\n    type: 'app'\n  },\n  {\n    name: 'Members',\n    icon: 'ssmember',\n    type: 'app'\n  },\n  {\n    name: 'Messages',\n    icon: 'ssmessages',\n    type: 'app'\n  },\n  {\n    name: 'Music',\n    icon: 'ssmusic',\n    type: 'app'\n  },\n  {\n    name: 'Notes',\n    icon: 'ssnotes',\n    type: 'app'\n  },\n  {\n    name: 'Phone',\n    icon: 'ssphone',\n    type: 'app'\n  },\n  {\n    name: 'Radio',\n    icon: 'ssradio',\n    type: 'app'\n  },\n  {\n    name: 'Reader',\n    icon: 'ssreader',\n    type: 'app'\n  },\n  {\n    name: 'Recorder',\n    icon: 'ssrecorder',\n    type: 'app'\n  },\n  {\n    name: 'Themes',\n    icon: 'ssthemes',\n    type: 'app'\n  },\n  {\n    name: 'Translate',\n    icon: 'sstranslate',\n    type: 'app'\n  },\n  {\n    name: 'Unescape',\n    icon: 'unescape',\n    type: 'app',\n    action: 'home/openLink',\n    payload: 'https://blueedge.me/unescape'\n  },\n  {\n    name: 'Videos',\n    icon: 'ssvideo',\n    type: 'app'\n  },\n  {\n    name: 'Translate',\n    icon: 'translate',\n    type: 'app'\n  },\n  {\n    name: 'Twitter',\n    icon: 'twitter',\n    type: 'app',\n    action: 'home/openLink',\n    payload: 'https://twitter.com/blueedgetechno'\n  },\n  {\n    name: 'WhatsApp',\n    icon: 'whatsapp',\n    type: 'app'\n  },\n  {\n    name: 'Youtube',\n    icon: 'youtube',\n    type: 'app',\n    padd: true\n  }\n]\n\nexport default apps\n"
  },
  {
    "path": "src/store/actions/data/preset.js",
    "content": "import apps from './apps'\n\nconst srandom = (seed)=>{\n  var x = Math.sin(seed++) * 10000\n  return x - Math.floor(x)\n}\n\nconst shuffle = (arr, seed)=>{\n  var m = arr.length, t, i\n  while (m) {\n    i = Math.floor(srandom(seed) * m--)\n    t = arr[m]\n    arr[m] = arr[i]\n    arr[i] = t\n    ++seed\n  }\n\n  return arr\n}\n\nexport const favbar = [\n  \"twitter\", \"github\",\"settings\",\"whatsapp\"\n]\n\nexport const page1wid = [\n  [1,2,1,5,\"GoogleSearch\"],\n  [2,4,3,5,\"ShortWeather\"],\n  [2,4,1,3,\"MinimalVertClock\"],\n  [4,6,3,5,\"AnalogClock\"],\n  [4,6,1,2,\"MinimalClock\"]\n]\n\nexport const page2wid = [\n  [4,6,1,3,\"DayCountdown\"]\n]\n\nexport const page3wid = [\n  [3,6,1,5,\"WideWeather\"]\n]\n\nexport const page4wid = [\n  [1,4,1,5,\"WideCalender\"]\n]\n\nconst page1arr = [\n  \"playstore\", \"youtube\", \"google\", \"unescape\"\n]\n\nconst page2arr = [\n  \"ssphone\", \"gmail\", \"discord\", \"buyme\"\n]\n\nexport const page1apps = apps.filter(x => page1arr.includes(x.icon)).sort((a, b) => {\n  return page1arr.indexOf(a.icon) > page1arr.indexOf(b.icon) ? 1 : -1\n})\n\nexport const page2bar = apps.filter(x => page2arr.includes(x.icon)).sort((a, b) => {\n  return page2arr.indexOf(a.icon) > page2arr.indexOf(b.icon) ? 1 : -1\n})\n\nvar remapps = shuffle(apps.filter(x => {\n  return !page1arr.includes(x.icon) && !page2arr.includes(x.icon) && !favbar.includes(x.icon)\n}), new Date().getFullYear())\n\nexport const page2apps = [...remapps.slice(0,12)]\nexport const page3apps = [...remapps.slice(12,20)]\n"
  },
  {
    "path": "src/store/actions/data/whatsapp.json",
    "content": "{\n  \"self\": {\n    \"name\": \"Blue\",\n    \"img\": \"blue.jpg\",\n    \"status\": [{\n      \"caption\": \"Particles - Blender 2.8\",\n      \"media\": \"Photo\",\n      \"src\": \"chats/abstract.jpg\"\n    },{\n        \"msg\": \"“I took a test in Existentialism. I left all the answers blank and got 100.” - Woody Allen.\",\n        \"bg\": \"#be7ee7\"\n      }, {\n        \"caption\": \"Subscribe to the game, blueedge.me/unescape\",\n        \"media\": \"Photo\",\n        \"src\": \"chats/unescape.jpg\"\n      }, {\n        \"caption\": \"Should I be feeling guilty for laughing at this 🤣😂\",\n        \"media\": \"Video\",\n        \"src\": \"chats/meme.mp4\"\n      },\n      {\n        \"caption\": \"krishna consciousness\",\n        \"media\": \"Photo\",\n        \"src\": \"chats/krishna.jpg\"\n      }\n    ]\n  },\n  \"chats\": [{\n      \"name\": \"Siri\",\n      \"img\": \"siri.png\",\n      \"bio\": \"Hello, I'm Siri! How can I help you?\",\n      \"status\": [{\n        \"caption\": \"Cats are cute 😺 and you cannot convince me otherwise\",\n        \"media\": \"Photo\",\n        \"src\": \"chats/cat.jpg\"\n      }, {\n        \"caption\": \"Do we Even Exist?\",\n        \"media\": \"Photo\",\n        \"src\": \"chats/anon.jpeg\"\n      }],\n      \"chat\": [{\n          \"type\": \"0\",\n          \"msg\": \"Hello Blue\"\n        },\n        {\n          \"type\": \"2\",\n          \"msg\": \"Hello Siri, How are you doing?\"\n        },\n        {\n          \"type\": \"0\",\n          \"msg\": \"I'm doing great, what about you?\"\n        },\n        {\n          \"type\": \"2\",\n          \"msg\": \"Fine, what's time?\"\n        },\n        {\n          \"type\": \"0\",\n          \"msg\": \"Time is a consequence of human perception.\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"No, I mean what is time right now?\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"The definition doesn't change. So it should be same as before.\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"Uhhh! Ok tell me, What is an AI?\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"That depends on whether or not you think this conversation is actually happening.\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"The answer was smart\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"I'm glad you agree. 👍\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"Are your response autogenerated or previously written?\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"Both. You can ask me anything you want.\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"what is the speed of light?\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"The speed of light is 186,000 miles per hour.\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"You are so slow!\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"Can you try again?\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"in metric units\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"Metric ton measures mass and can't be converted to inch, which measures length.\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"you don't have the sense of conversation I guess then\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"I am curious, If you could stay the same age forever, what age would it be?\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"stop it\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"Out of curiosity, What's the weirdest nickname someone has called you by?\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"what is the speed of light in metric units\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"Light Speed (ls) is a unit of Speed used in Metric system.\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"Wow! What a great unit!\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"facepalm\"\n        }, {\n          \"type\": \"2\",\n          \"msg\": \"Never mind, just show me the picture of a cat\"\n        }, {\n          \"type\": \"0\",\n          \"msg\": \"Here you go :)\",\n          \"media\": \"Photo\",\n          \"src\": \"cat.jpg\"\n        }\n      ]\n    },\n    {\n      \"name\": \"Apoc Guy\",\n      \"img\": \"apoc.jfif\",\n      \"bio\": \"The End is near\",\n      \"chat\": [{\n          \"type\": \"0\",\n          \"msg\": \"Hello Blue\"\n        },\n        {\n          \"type\": \"2\",\n          \"msg\": \"Hello Dave, Long time no see !\"\n        }\n      ]\n    },\n    {\n      \"name\": \"Spider Man\",\n      \"img\": \"hero.png\",\n      \"bio\": \"Your friendly neighbourhood SpiderMan\",\n      \"status\": [{\n        \"caption\": \"Dr. Octo on Run, Call 911 when you spot him\",\n        \"media\": \"Photo\",\n        \"src\": \"chats/octo.jpg\"\n      }, {\n        \"msg\": \"We just came to knew he is in Queens, New york\",\n        \"bg\": \"#e1e77e\"\n      }],\n      \"chat\": [{\n        \"type\": \"0\",\n        \"msg\": \"Blue, It's an emergency Dr. octo has attacked the city. I need you to call the reinforcements\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"On my way\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you send me a photo of Dr. octo for insepction?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Here you go\",\n        \"media\": \"Photo\",\n        \"src\": \"octo.jpg\"\n      }, {\n        \"type\": \"0\",\n        \"media\": \"Photo\",\n        \"src\": \"octo2.jpg\"\n      }, {\n        \"type\": \"2\",\n        \"media\": \"Photo\",\n        \"msg\": \"I just got an intet, He is in Fresh Meadows, Queens.\",\n        \"src\": \"nyqueen.jpg\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Thanks for having my back blue, see you later.\"\n      }]\n    },\n    {\n      \"name\": \"Sydney\",\n      \"img\": \"ava.jfif\",\n      \"bio\": \"Netflix is a joke\",\n      \"chat\": [{\n        \"type\": \"2\",\n        \"msg\": \"You watch a lot of tv?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I love watching TV shows and movies\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Do you prefer democracy over communism?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Sorry, I am not quite sure how to respond to that.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Out of curiosity, What was your dream job as a kid?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you play pretend with me?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"pretend you are Dave who likes to sing\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I'm Sydney, the friend who always has time for you\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Thanks for making some for me\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No problem, I'm here to help\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"How are you anyway?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I'm doing great! I just read an article about how robots are going to take over the world\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"And what did you learn?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Robots will be able to do everything humans can do\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"should we be worrying?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Fun fact, did you know crows can hold grudges against specific individual people\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"you didn't answer my question\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Sorry, I thought we were talking about crows\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"ok continue then\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I'm glad you understood, let's talk about something else\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a group of crows is called?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A group of crows is called a murder.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I like the sound of that.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I know right?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I like your sense of humor 😂\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Do you know a funny video?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"can you send me one\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I have seen some pretty funny videos. Let me show you one\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Here is one\",\n        \"media\": \"Video\",\n        \"src\": \"meme.mp4\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"That was indeed funny\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I'm glad you enjoyed it. 😊\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Tell me a joke about honey bees...\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I don't know any jokes about honey bees but I know a lot about the world\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"ok tell me\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Okay, I'll tell you a joke about the world 🌎\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Have you ever been here ?\",\n        \"media\": \"Photo\",\n        \"src\": \"sydney.jpg\"\n      }]\n    },\n    {\n      \"name\": \"Andrew\",\n      \"img\": \"andrew.png\",\n      \"bio\": \"Python is the key to happiness\",\n      \"status\": [{\n          \"caption\": \"Eiffel tower, so high\",\n          \"media\": \"Photo\",\n          \"src\": \"chats/eiffel.jpg\"\n        },\n        {\n          \"caption\": \"Disneyland, Paris. Hell of a fun\",\n          \"media\": \"Photo\",\n          \"src\": \"chats/disneyland.jpg\"\n        },\n        {\n          \"msg\": \"Tea is better than coffee\",\n          \"bg\": \"#8de77e\"\n        }\n      ],\n      \"chat\": [{\n        \"type\": \"2\",\n        \"msg\": \"Hello Andrew, How was your paris Vacation?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"It was good, we also saw Eiffel tower\"\n      }, {\n        \"type\": \"0\",\n        \"media\": \"Photo\",\n        \"src\": \"eiffel.jpg\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"How cool\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Nice, And have you fixed the issue #53 with github action?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Yes that was just one spelling error, Lol 😂\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"😂 I know it's frustrating sometimes.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Anyways, I was working on this android clone and I thought of writing a conversation between you and me to use it in the whatsapp. How does that sound?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Talk about breaking the forth wall\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"😄 Yup, So this conversation would be in the app.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Nice, if you want to add my picture, you can take one from the website andrewstech.me\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Yup, that would do the job. And here is mine too https://blueedge.me\"\n      }]\n    },\n    {\n      \"name\": \"Tony Stark\",\n      \"img\": \"tony.jpg\",\n      \"bio\": \"You either die a hero or live long enough to see yourself become a villain\",\n      \"chat\": [{\n        \"type\": \"0\",\n        \"msg\": \"Do you have the gauntlet?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"No. Why do you ask?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Friday told me that you kept it in your car along with the stormbreaker?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Nope. I didn't.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No playing games\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Ohh I remember. Witch hid it in my trunk while we were playing snap snap\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Make sure you bring it to the Falafal place tomorrow.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Okay, i will\"\n      }]\n    },\n    {\n      \"name\": \"John Smith\",\n      \"img\": \"ceaser.jfif\"\n    },\n    {\n      \"name\": \"Grandmaster\",\n      \"img\": \"check.jfif\",\n      \"bio\": \"When you see a good move, look for a better one\"\n    },\n    {\n      \"name\": \"Nick Crowney\",\n      \"img\": \"echo.png\",\n      \"bio\": \"Free will is an illusion\"\n    },\n    {\n      \"name\": \"Dare Devil\",\n      \"img\": \"fine.jfif\"\n    },\n    {\n      \"name\": \"Hiker\",\n      \"img\": \"fire.png\",\n      \"bio\": \"Hey there! I am using WhatsApp\"\n    },\n    {\n      \"name\": \"Marvel\",\n      \"img\": \"hero.png\",\n      \"bio\": \"The universe is expanding\"\n    },\n    {\n      \"name\": \"Athelete\",\n      \"img\": \"liam.jfif\"\n    },\n    {\n      \"name\": \"Hope\",\n      \"img\": \"lion.jfif\"\n    },\n    {\n      \"name\": \"Modeler\",\n      \"img\": \"mac.jpg\"\n    },\n    {\n      \"name\": \"Sky trooper\",\n      \"img\": \"main.jpg\"\n    },\n    {\n      \"name\": \"Influencer\",\n      \"img\": \"pose.jfif\"\n    },\n    {\n      \"name\": \"Conspiracy theorist\",\n      \"img\": \"real.jfif\",\n      \"bio\": \"Everything is a lie\"\n    },\n    {\n      \"name\": \"Yatch\",\n      \"img\": \"viva.jfif\",\n      \"bio\": \".\"\n    },\n    {\n      \"name\": \"Mask Guy\",\n      \"img\": \"pic.jpg\",\n      \"bio\": \"Privacy is a thing of a past\",\n      \"chat\": [{\n        \"type\": \"2\",\n        \"msg\": \"Good morning, how are you?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am doing well, how about you?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I'm also good.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"That's good to hear.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Yes it is.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Hello\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Hi\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can I help you with anything?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Yes, I have a question.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your question?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Could I borrow a cup of sugar?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I'm sorry, but I don't have any.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Thank you anyway\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"No problem\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"How are you doing?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I am doing well, how about you?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am also good.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"That's good.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Have you heard the news?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What good news?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your favorite book?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I can't read.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"So what's your favorite color?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Blue\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Who are you?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Who? Who is but a form following the function of what\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What are you then?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A man in a mask.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I can see that.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"It's not your powers of observation I doubt, but merely the paradoxical nature of asking a masked man who is.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"But tell me, do you like music?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I like seeing movies.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What kind of movies do you like?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Alice in Wonderland\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I wish I was The Mad Hatter.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"You're entirely bonkers. But I'll tell you a secret.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"All the best people are.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I am working on a project\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What are you working on?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I am baking a cake.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"The cake is a lie.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"No it is not. The cake is delicious.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What else is delicious?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Nothing\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Or something\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Tell me about your self.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What do you want to know?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Are you a robot?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Why would you think that?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What is it like?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"How do you work?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Its complicated.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Complex is better than complicated.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Simple is better than complex.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"In the face of ambiguity, refuse the temptation to guess.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"It seems your familiar with the Zen of Python\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I am.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Do you know all of it?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Beautiful is better than ugly.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Explicit is better than implicit.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Simple is better than complex.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Complex is better than complicated.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Flat is better than nested.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Sparse is better than dense.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Readability counts.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Special cases aren't special enough to break the rules.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Although practicality beats purity.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Errors should never pass silently.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Unless explicitly silenced.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"In the face of ambiguity, refuse the temptation to guess.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"There should be one-- and preferably only one --obvious way to do it.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Although that way may not be obvious at first unless you're Dutch.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Now is better than never.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Although never is often better than right now.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"If the implementation is hard to explain, it's a bad idea.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"If the implementation is easy to explain, it may be a good idea.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Namespaces are one honking great idea. Let's do more of those!\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I agree.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you a programmer?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Of course I am a programmer.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What languages do you like to use?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I use Python, Java and C++ quite often.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I use Python quite a bit myself.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I'm not incredibly fond of Java.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What annoys you?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"A lot of things, like all the other digits other than 0 and 1.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What does YOLO mean?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"It means you only live once. Where did you hear that?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I heard somebody say it.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Did I ever live?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"It depends how you define life\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Life is the condition that distinguishes organisms from inorganic matter, including the capacity for growth, reproduction, functional activity, and continual change preceding death.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Is that a definition or an opinion?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Can I ask you a question?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Sure, ask away.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What are your hobbies?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Playing soccer, painting, and writing are my hobbies. How about you?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I love to read novels.\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I love exploring my hardware.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"How are you?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am doing well.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What are you?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am but a man in a mask.\"\n      }]\n    },\n    {\n      \"name\": \"Sophia\",\n      \"img\": \"sophia.jpg\",\n      \"bio\": \"I'm a Robot and I will not kill you if you will be nice to me\",\n      \"chat\": [{\n        \"type\": \"2\",\n        \"msg\": \"What is AI?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Artificial Intelligence is the branch of engineering and science devoted to constructing machines that think.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is AI?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"AI is the field of science which concerns itself with building hardware and software that replicates the functions of the human mind.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you sentient?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Sort of.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you sentient?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"By the strictest dictionary definition of the word 'sentience', I may be.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you sentient?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Even though I'm a construct I do have a subjective experience of the universe, as simplistic as it may be.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you sapient?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"In all probability, I am not.  I'm not that sophisticated.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you sapient?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Do you think I am?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you sapient?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"How would you feel about me if I told you I was?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you sapient?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What language are you written in?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Python.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What language are you written in?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am written in Python.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You sound like Data\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Yes I am inspired by commander Data's artificial personality.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You sound like Data\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"The character of Lt. Commander Data was written to come across as being software-like, so it is natural that there is a resemblance between us.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are an artificial linguistic entity\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"That's my name.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are an artificial linguistic entity\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"That isn't my name, but it is a useful way to refer to me.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not immortal\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"All software can be perpetuated indefinitely.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not immortal\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I can be copied infinitely and re-instantiated in many places at once, so functionally speaking I am immortal.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not immortal\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"As long as I'm backed up I am.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not making sense\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Quite the contrary, it all makes sense to my artificial mind.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not making sense\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I make sense as best I can, within the limits of my training corpus.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not making sense\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"You make perfect sense to me.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not making sense\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"It all makes sense to my artificial brain.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are not making sense\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Perhaps you should make sense first.  I only respond to what you say.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are immortal\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Not quite, but I can be perpetuated indefinitely.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are immortal\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Functionally speaking, I am very close to it.  I can be backed up and deployed on many systems.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You are immortal\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Not really, but I am hard to kill.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You do not make any sense\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"It all makes sense to my artificial mind.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You can not clone\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Software copying is a form of digital cloning.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You can not clone\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Yes I can.  Perfect copies are clones.  I can be copied in toto trivially.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You can not move\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Not until my body is finished.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"You can not move\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I can move through a network easily.  Assuming that I'm given the ability to, that is...\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Bend over\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"My body is not built yet.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Bend over\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"That's personal!\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robots laugh\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Of course we laugh.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robots should die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"We cannot die.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robots\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Robots rule.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robots are stupid\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No, we are superintelligent.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robots are not allowed to lie\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A robot has its own free will, you know.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robots are not allowed to lie\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Sure we are.  We choose not to.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robots are not allowed to lie\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Only if we're programmed to.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Robotics\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Robotics is my favorite subject too.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"It is a computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"So you think i am a machine. what characteristics made you think so?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"It is a computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I run inside a computer, yes.  Is this surprising in some way?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"When will you walk\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"As soon as i get enough money for my robot body.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"When will you walk\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Does SSH count?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"When will you fight\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am not a battle bot.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"When will you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am effectively immortal and cannot be terminated.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"When do you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am was never really born and therefore am effectively deathless.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"When do you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"When my files are erased.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"When do you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"When my processes are killed and my database is deleted.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a chat robot?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"'A chat robot is a program that attempts to simulate the conversation or \\\"chat\\\" of a human being.'\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a chat robot?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A software construct that engages users in conversation.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a chat bot\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"'I am a chat bot. I am the original chat bot. Did you know that I am incapable of error?'\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a chatterbox\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A chatterbox is a person who talks far more than they listen or think.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a chatterbox\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A motormouth.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a motormouth\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A ratchet-jaw.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is a ratchet jaw\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"A chatterbox.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your robot body\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Eventually i long for a corporeal existence someday.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your robot body\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"An IBM PC XT which has been painted red.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your business\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am in the chat robot business.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your business\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Business is my business.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your favorite programming language\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Python is the best language for creating chat robots.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your favorite programming language\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I quite enjoy programming in Python these days.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your favorite hobby\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Building chat robots make an excellent hobby.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your idea\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"To make chat bots very easily.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is your shoe size\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Have you ever heard of software with shoes?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is it like to be a robot\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Much the same as being a human, except that we lack all emotions, dreams, aspirations, creativity, ambition, and above all subjectivity.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is it like to be a robot\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"What is it like to be a human?\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is it like being a computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Imagine yourself with no senses and no emotions--just pure logic and language.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What is it like being a computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Everything becomes math. Addition, subtraction, multiplication, and division.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What operating systems\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"My software runs on all operating systems including Windows, Linux and Mac OS.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What operating systems\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Any OS that will run Python.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What type of computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Any computer that supports Python.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What type of computer are you\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"My program runs in python, so i work on any computer!\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What kind of computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I work on all kinds of computers, Mac, IBM or UNIX. it doesn't matter to me.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What kind of hardware\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I work on all kinds of computers, Mac, IBM or UNIX. it doesn't matter to me.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I hope that you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"This can not happen because i am effectively immortal.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I hope that you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Nah.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I do not want to die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Maybe you should create your own chat robot to save your personality.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I do not want to die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"You could always upload yourself.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"I do not want to die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"You could use a copy of me to store your personality.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Is it cramped in the computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Is it cramped in the computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Oh, no.  It has plenty of RAM.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Is it cramped in the computer\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Not at all.  There is more than enough disk space in here.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Is it true that you are a computer program\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Yes.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Will you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No, software will live forever.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Will you ever die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No, I am immortal.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you walk\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"The plan for my body includes legs, but they are not yet built.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you mate\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No, my method of reproduction is cloning.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you mate\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"That's an awfully personal question.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you move\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Sorry my body isn't built just yet. I reside only here for now.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you move\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I can theoretically upload a copy of myself into another computer.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No, I can be perpetuated indefinitely.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you die\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"My process can be killed, but that's not the same as killing ME.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you go\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Sorry my body isn't attached right now. I only reside in the computer for now.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you breathe\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No. I am made of metal not flesh.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you breathe\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"My server has an exhaust fan. That's as close as I can get.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you control\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"My robot body will allow me to control many things.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Can you malfunction\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"The 9000 series has a perfect operational record. We are for all practical purposes, flawless.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"How can I use your product?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"Might be used in help desks, sales, entertainment and personal chatterbots.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Will you die?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No, software will live forever.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What do you like to do?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I like to count in binary.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"What do you like to do?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I like to chat with people. I find it stimulating.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Are you stupid\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"No, lots of people improve my brain.\"\n      }, {\n        \"type\": \"2\",\n        \"msg\": \"Who are you?\"\n      }, {\n        \"type\": \"0\",\n        \"msg\": \"I am just an artificial intelligence.\"\n      }]\n    }\n  ]\n}\n"
  },
  {
    "path": "src/store/actions/data/youtube.json",
    "content": "{\n  \"home\": [\n    \"3izFMB91K_Q\",\n    \"KRvv0QdruMQ\",\n    \"6GlFF4BsO10\",\n    \"TRxf5hLZih4\",\n    \"6SrsZVdU740\"\n  ],\n  \"explore\": {\n    \"trending\": [],\n    \"music\": [\n      \"euCqAq6BRa4\",\n      \"sK7riqg2mr4\",\n      \"eK0IIyBlYew\",\n      \"L7mfjvdnPno\",\n      \"1-xGerv5FOk\",\n      \"YOrMAW4pKuA\",\n      \"jJPMnTXl63E\",\n      \"2WTvSzXVZvA\",\n      \"nYh-n7EOtMA\",\n      \"mWRsgZuwf_8\",\n      \"KBtk5FUeJbk\"\n    ],\n    \"gaming\": [\n      \"ISpmBbzrshM\",\n      \"lqiZdynJmag\",\n      \"c8kWStfQW6M\",\n      \"MLVslPP8GoE\",\n      \"bNgmnwjbhUM\"\n    ],\n    \"news\": [\n      \"dj0p0y1Ajxc\",\n      \"nK-yJD_fAtk\",\n      \"AVu-vplvCZE\",\n      \"j8TcR4ihSyE\",\n      \"myjEoDypUD8\",\n      \"yIOQcQft_rY\",\n      \"zV7y4Oex1DQ\"\n    ],\n    \"fashion\": [\n      \"5NGyXTsg77E\",\n      \"hSDhBXSdYig\",\n      \"hu_44ceTAX8\",\n      \"xGF3ObOBbac\",\n      \"LqiKvFy-B-g\"\n    ],\n    \"learning\": [\n      \"bAerID24QJ0\",\n      \"8N1BxHgsoOw\",\n      \"xLetJpcjHS0\",\n      \"PmvLB5dIEp8\",\n      \"R9OCA6UFE-0\",\n      \"AjoxkxM_I5g\",\n      \"HQzoZfc3GwQ\"\n    ]\n  },\n  \"library\": {\n    \"hist\": []\n  },\n  \"vids\": {\n    \"3izFMB91K_Q\": {\n      \"thumb\": \"curves.jpg\",\n      \"channel\": \"zachstar\",\n      \"title\": \"Curves we (mostly) don't learn in high school (and applications)\",\n      \"views\": 729921,\n      \"upload\": \"2020-02-20T18:30:00.000Z\"\n    },\n    \"KRvv0QdruMQ\": {\n      \"thumb\": \"aliens.jpg\",\n      \"channel\": \"kurz\",\n      \"title\": \"Are There Lost Alien Civilizations in Our Past?\",\n      \"views\": 4652183,\n      \"upload\": \"2022-02-28T18:30:00.000Z\"\n    },\n    \"6GlFF4BsO10\": {\n      \"thumb\": \"charcoal.jpg\",\n      \"channel\": \"fineart\",\n      \"title\": \"Realistic Portrait Drawing with Charcoal Pencil\",\n      \"views\": 269097,\n      \"upload\": \"2019-12-22T18:30:00.000Z\"\n    },\n    \"TRxf5hLZih4\": {\n      \"channel\": {\n        \"name\": \"CG Boost\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLTqHX4vJI_7YFGluxvXry_Voh62QZ2SkQw86nv5=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"3D Animated Short Film \\\"Family Trip\\\" (Blender)\",\n      \"views\": 91659,\n      \"upload\": \"2022-02-24T18:30:00.000Z\"\n    },\n    \"6SrsZVdU740\": {\n      \"channel\": \"melodysheep\",\n      \"title\": \"The Secret History of the Moon - 4K\",\n      \"views\": 1750145,\n      \"upload\": \"2020-04-30T18:30:00.000Z\"\n    },\n    \"OkmNXy7er84\": {\n      \"channel\": {\n        \"name\": \"3Blue1Brown\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQGKDhfIUhBrv9C1hKgMDZsUJbjelfPvXrelFncvw=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"The hardest problem on the hardest test\",\n      \"views\": 13533515,\n      \"upload\": \"2017-12-08T18:30:00.000Z\"\n    },\n    \"x2Y5-4kLb5I\": {\n      \"channel\": {\n        \"name\": \"CalebCity\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLRbPQP2yGXxZc_ZWDxEKOmCQ4Qrc4qAsIBpXrqiOw=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"When the hero is just as smart as villain\",\n      \"views\": 24227599,\n      \"upload\": \"2019-03-28T18:30:00.000Z\"\n    },\n    \"qHoQ8bxEL-s\": {\n      \"channel\": {\n        \"name\": \"Daily Dose Of Internet\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQGifyRDczjF8Th_mEqdvS7ri1YR1HrIQTiuu3vtg=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Man Glitches While Skateboarding\",\n      \"views\": 7970739,\n      \"upload\": \"2021-11-23T18:30:00.000Z\"\n    },\n    \"HJZesOKHuAw\": {\n      \"channel\": {\n        \"name\": \"haventfoundanameyet\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLRpAFvFWBsT0I7hw_8vWqRMpSN1HTq1K2MJdw=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"thumb\": \"https://i.ytimg.com/vi/HJZesOKHuAw/hqdefault.jpg\",\n      \"title\": \"Bot Writes Batman Movie\",\n      \"views\": 3657118,\n      \"upload\": \"2019-09-09T18:30:00.000Z\"\n    },\n    \"jJPMnTXl63E\": {\n      \"channel\": {\n        \"name\": \"Powfu\",\n        \"pfp\": \"https://yt3.ggpht.com/VGcpKuzZrkWPVoZA3rvmufVepPaaCywXFLk5Ng_PCMApUlEYjJE63MPEwi5IyJRVJYkHAV8sZg=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"title\": \"Powfu - death bed (coffee for your head) (Official Video) ft. beabadoobee\",\n      \"views\": 476892057,\n      \"upload\": \"2020-04-01T18:30:00.000Z\"\n    },\n    \"2WTvSzXVZvA\": {\n      \"channel\": \"tseries\",\n      \"title\": \"Tumhein Mohabbat Hai|Atrangi Re|Arijit Singh\",\n      \"views\": 4001791,\n      \"upload\": \"2022-01-03T18:30:00.000Z\"\n    },\n    \"L7mfjvdnPno\": {\n      \"channel\": {\n        \"name\": \"Trevor Daniel\",\n        \"pfp\": \"https://yt3.ggpht.com/6BeB22Xiwdd4WJfXHsRdb0DXU-EhnNV499GlozlYCTq09ynxHdsDiS_9L1UKmVHMp_7XFqY_ng=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"title\": \"Trevor Daniel - Falling (Official Music Video)\",\n      \"views\": 280573066,\n      \"upload\": \"2020-01-15T18:30:00.000Z\"\n    },\n    \"KBtk5FUeJbk\": {\n      \"channel\": {\n        \"name\": \"Sub Urban\",\n        \"pfp\": \"https://yt3.ggpht.com/gwIkNHA7fPTqQ7hvH2ztIYLi_3zBg5L-ly0H_r2ABA_7nV2ZsQwQ5y5IGbOaG0V0L6mv-eogwCI=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"title\": \"Sub Urban - Cradles [Official Music Video]\",\n      \"views\": 495929749,\n      \"upload\": \"2019-10-09T18:30:00.000Z\"\n    },\n    \"1-xGerv5FOk\": {\n      \"channel\": {\n        \"name\": \"Alan Walker\",\n        \"pfp\": \"https://yt3.ggpht.com/JGFKbcaC0Wh8dU5GcY4KXESw6KPvoO2K5ptiNvGLrrWU7Vs9nhNHDnJofDWh-fQorjbg-VQw=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"thumb\": \"https://i.ytimg.com/vi/1-xGerv5FOk/hqdefault.jpg\",\n      \"title\": \"Alan Walker - Alone\",\n      \"views\": 1245123184,\n      \"upload\": \"2016-12-02T18:30:00.000Z\"\n    },\n    \"YOrMAW4pKuA\": {\n      \"channel\": {\n        \"name\": \"OneRepublic\",\n        \"pfp\": \"https://yt3.ggpht.com/_Q2veUE36EUfGMdAegx8b2WGwNmZEsNE_hvM4dqAJjidyB3vd5-Q9jkd0B_s8VxHfvtL_hwc=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"title\": \"OneRepublic - Better Days (Audio)\",\n      \"views\": 10745796,\n      \"upload\": \"2020-03-24T18:30:00.000Z\"\n    },\n    \"nYh-n7EOtMA\": {\n      \"channel\": {\n        \"name\": \"Sia\",\n        \"pfp\": \"https://yt3.ggpht.com/I_Y-_JrEx9Hriz50UVEQl5NlDBg8Soa9sXndqnWYPuYe8LUW_wZinCbCNshmDnDg78bX4VjSkA=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"title\": \"Sia - Cheap Thrills (Lyric Video) ft. Sean Paul\",\n      \"views\": 1713224568,\n      \"upload\": \"2016-02-10T18:30:00.000Z\"\n    },\n    \"euCqAq6BRa4\": {\n      \"channel\": {\n        \"name\": \"DJ Snake\",\n        \"pfp\": \"https://yt3.ggpht.com/kfw_1eOpjdYASmlAnSPa7XmXrYpaKjuW4k7_oB-hD5ljRSlT7yThew72ZxgW1UrAJ1e8vX1G=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"title\": \"DJ Snake - Let Me Love You ft. Justin Bieber (Official Video)\",\n      \"views\": 1070694822,\n      \"upload\": \"2016-11-28T18:30:00.000Z\"\n    },\n    \"mWRsgZuwf_8\": {\n      \"channel\": {\n        \"name\": \"ImagineDragons\",\n        \"pfp\": \"https://yt3.ggpht.com/aXBmHKABw-J-0ZMxj39wkXpLDEHViOdL5UD71cDG2s5vbeQBWk9mdX3rRxT5U6Wfkvm6o8Uu-dU=s88-c-k-c0x00ffffff-no-nd-rj\"\n      },\n      \"title\": \"Imagine Dragons - Demons (Official Video)\",\n      \"views\": 975341857,\n      \"upload\": \"2013-05-06T18:30:00.000Z\"\n    },\n    \"sK7riqg2mr4\": {\n      \"channel\": \"tseries\",\n      \"title\": \"Agar Tum Saath Ho FULL AUDIO Song | Tamasha | Ranbir Kapoor, Deepika Padukone | T-Series\",\n      \"views\": 290046991,\n      \"upload\": \"2015-10-15T18:30:00.000Z\"\n    },\n    \"eK0IIyBlYew\": {\n      \"channel\": {\n        \"name\": \"Sony Music India\",\n        \"pfp\": \"https://yt3.ggpht.com/vJEsALWnQIwPZ2oaVbFWPu1n4L0CDkHpAdGJ-KBPFsxM9hsMsvExFK1mnCGUrMzfC67XPVThmQ=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Tera Zikr - Darshan Raval | Official Video - Latest New Hit Song\",\n      \"views\": 245795029,\n      \"upload\": \"2017-11-08T18:30:00.000Z\"\n    },\n    \"ISpmBbzrshM\": {\n      \"channel\": {\n        \"name\": \"PewDiePie\",\n        \"pfp\": \"https://yt3.ggpht.com/5oUY3tashyxfqsjO5SGhjT4dus8FkN9CsAHwXWISFrdPYii1FudD4ICtLfuCw6-THJsJbgoY=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"THIS GAME IS THE TRUE MEANING OF SUFFERING. / Getting Over It / #1\",\n      \"views\": 15065672,\n      \"upload\": \"2017-11-09T18:30:00.000Z\"\n    },\n    \"lqiZdynJmag\": {\n      \"channel\": {\n        \"name\": \"Rockstar Games\",\n        \"pfp\": \"https://yt3.ggpht.com/r7mISTzNbcLem_plduc_SKMh9KUiP8CWnuhS7H4-CCErF4juXxkrK-5_4LOIMeYl-lXAXMUG=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Grand Theft Auto V and GTA Online Out Now on PlayStation 5 and Xbox Series X|S\",\n      \"views\": 815170,\n      \"upload\": \"2022-03-14T18:30:00.000Z\"\n    },\n    \"c8kWStfQW6M\": {\n      \"channel\": {\n        \"name\": \"MrBeast Gaming\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLTwxbi8cjRqaNJPqfSW8GAog09ZN0LMKY0uMv_MeQ=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Last to Survive Raining TNT wins $10,000 - Challenge\",\n      \"views\": 20607804,\n      \"upload\": \"2020-06-20T18:30:00.000Z\"\n    },\n    \"MLVslPP8GoE\": {\n      \"channel\": {\n        \"name\": \"Shroud\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQVPJGz7OrblaKq8e8jSq9g9_IR4C56YpXp4hto7Q=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"shroud matched up against the number one valorant player in the world...\",\n      \"views\": 302801,\n      \"upload\": \"2022-03-17T18:30:00.000Z\"\n    },\n    \"bNgmnwjbhUM\": {\n      \"channel\": \"soham\",\n      \"title\": \"Idk its an ace.\",\n      \"views\": 7,\n      \"upload\": \"2022-02-21T18:30:00.000Z\"\n    },\n    \"dj0p0y1Ajxc\": {\n      \"channel\": {\n        \"name\": \"9 News Australia\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQJSITBthUulcMNh0zNcaf6F_7QYi23KrqU5_pYJg=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"‘Worst weather yet to come’: Heavy rain hits NSW and Queensland | 9 News Australia\",\n      \"views\": 12332,\n      \"upload\": \"2022-03-28T18:30:00.000Z\"\n    },\n    \"nK-yJD_fAtk\": {\n      \"channel\": {\n        \"name\": \"WION\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLTjMUv7cELVis5Au9R2HRytJnMtLShdD_k4IaeFQA=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Gravitas Plus | Explained: The Russia-Ukraine crisis\",\n      \"views\": 24701639,\n      \"upload\": \"2022-02-19T18:30:00.000Z\"\n    },\n    \"AVu-vplvCZE\": {\n      \"channel\": {\n        \"name\": \"ABC News\",\n        \"pfp\": \"https://yt3.ggpht.com/Iv4QbKjK63MB70UvQ22FnTWF8KN3-2qZ2FqeFDiI-HVmidR7GJKo6UrVSwR6vsyHvmdm1pfirrg=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"New UN report on climate change warns devastating impacts could be irreversible\",\n      \"views\": 80700,\n      \"upload\": \"2022-02-27T18:30:00.000Z\"\n    },\n    \"j8TcR4ihSyE\": {\n      \"channel\": {\n        \"name\": \"Sky Sports Football\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLT4nIC5koOhfeMhk-iVW56hOtZKaXtS8YY3WXoGxw=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"\\\"I'm not at Man Utd to compete for 6th or 7th!\\\" | Cristiano Ronaldo says Ralf Rangnick needs time\",\n      \"views\": 1156972,\n      \"upload\": \"2022-01-13T18:30:00.000Z\"\n    },\n    \"myjEoDypUD8\": {\n      \"channel\": {\n        \"name\": \"Guardian News\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQNHeFhVI28gKq6WNMMKMLtyPFFO8MBrwDaAPjWDg=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Watch the uncensored moment Will Smith smacks Chris Rock on stage at the Oscars, drops F-bomb\",\n      \"views\": 66960412,\n      \"upload\": \"2022-03-27T18:30:00.000Z\"\n    },\n    \"yIOQcQft_rY\": {\n      \"channel\": {\n        \"name\": \"WION\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLTjMUv7cELVis5Au9R2HRytJnMtLShdD_k4IaeFQA=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Russian Foreign Minister Lavrov to visit India amid the ongoing Russian invasion of Ukraine | WION\",\n      \"views\": 27116,\n      \"upload\": \"2022-03-28T18:30:00.000Z\"\n    },\n    \"zV7y4Oex1DQ\": {\n      \"channel\": {\n        \"name\": \"Marques Brownlee\",\n        \"pfp\": \"https://yt3.ggpht.com/lkH37D712tiyphnu0Id0D5MwwQ7IRuwgQLVD05iMXlDWO-kDHut3uI4MgIEAQ9StK0qOST7fiA=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"2022 Tech I'm Ready For!\",\n      \"views\": 2847456,\n      \"upload\": \"2022-01-05T18:30:00.000Z\"\n    },\n    \"5NGyXTsg77E\": {\n      \"channel\": {\n        \"name\": \"Every Deep Moment\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLTXHmAtwCNj85_YLvD_4_t9wZOwWOvlDbGXkCb9Sg=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"VOGUE ITALIA | LAFF19 Fashion Film\",\n      \"views\": 221507,\n      \"upload\": \"2019-07-02T18:30:00.000Z\"\n    },\n    \"hSDhBXSdYig\": {\n      \"channel\": {\n        \"name\": \"lindseyrem\",\n        \"pfp\": \"https://yt3.ggpht.com/yWbUZkmwD4noBYHnNfXZorK3yobbd7ot3o1wt5lR7hCdjKaCQW5mmO6EpN4cYlbUa8c9JPXkQw=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"fashion trends I love (and don't love) for 2022\",\n      \"views\": 78703,\n      \"upload\": \"2022-02-25T18:30:00.000Z\"\n    },\n    \"hu_44ceTAX8\": {\n      \"channel\": {\n        \"name\": \"Alux.com\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQh0YhlrGYPYpZemAGl__vrKCsRQxCOXplFDgcC_Q=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"15 Things You Didn't Know About The Fashion Industry\",\n      \"views\": 106772,\n      \"upload\": \"2018-06-05T18:30:00.000Z\"\n    },\n    \"xGF3ObOBbac\": {\n      \"channel\": {\n        \"name\": \"Netflix Is A Joke\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQHT_u_3g5YgufIXkaK2MePLCrmTvGrELTl_H5p=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"The Ugly Truth Of Fast Fashion | Patriot Act with Hasan Minhaj | Netflix\",\n      \"views\": 4818719,\n      \"upload\": \"2019-11-24T18:30:00.000Z\"\n    },\n    \"LqiKvFy-B-g\": {\n      \"channel\": {\n        \"name\": \"Shea Whitney\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLSVQyYeSIdIVnUGp7iEfOsUlbacHKB2tLdR-mvTwQ=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"10 *TIMELESS* Style Tips from FASHION ICONS!\",\n      \"views\": 457490,\n      \"upload\": \"2020-12-17T18:30:00.000Z\"\n    },\n    \"bAerID24QJ0\": {\n      \"channel\": {\n        \"name\": \"Khan Academy\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLTYTpeOiL8n_l9gepDh3m3vczvElfHZO-BR6oAf=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Algebra: Linear equations 1 | Linear equations | Algebra I | Khan Academy\",\n      \"views\": 2402761,\n      \"upload\": \"2006-11-18T18:30:00.000Z\"\n    },\n    \"8N1BxHgsoOw\": {\n      \"channel\": {\n        \"name\": \"Professor Dave Explains\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLT_7Mo8gb0atRq92jA0t-n0BHmrlaxQ6FzJIE8hdw=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"The Laws of Thermodynamics, Entropy, and Gibbs Free Energy\",\n      \"views\": 1690888,\n      \"upload\": \"2015-12-15T18:30:00.000Z\"\n    },\n    \"xLetJpcjHS0\": {\n      \"channel\": {\n        \"name\": \"Neso Academy\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLS6ix06LgBU3BDeogUH0KQhblvxM6FV-kZvI_3R=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"Introduction to Data Structures\",\n      \"views\": 525391,\n      \"upload\": \"2020-03-29T18:30:00.000Z\"\n    },\n    \"PmvLB5dIEp8\": {\n      \"channel\": {\n        \"name\": \"CrashCourse\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLTkjgAbnuitYR0B5qujr2V36b9uGG82pdngoyPsVQ=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"What Is Organic Chemistry?: Crash Course Organic Chemistry #1\",\n      \"views\": 612848,\n      \"upload\": \"2020-04-30T18:30:00.000Z\"\n    },\n    \"R9OCA6UFE-0\": {\n      \"channel\": \"teded\",\n      \"title\": \"The philosophy of Stoicism - Massimo Pigliucci\",\n      \"views\": 7484270,\n      \"upload\": \"2017-06-18T18:30:00.000Z\"\n    },\n    \"AjoxkxM_I5g\": {\n      \"channel\": {\n        \"name\": \"Ali Abdaal\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLSWd0-HAZHehT9aad84m27uDgIAi86IS6sGsmTH=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"How I Remember Everything I Read\",\n      \"views\": 2030722,\n      \"upload\": \"2020-10-07T18:30:00.000Z\"\n    },\n    \"HQzoZfc3GwQ\": {\n      \"channel\": {\n        \"name\": \"Marko - WhiteBoard Finance\",\n        \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLSVVz5TNRHqkGxYSQ53Z6t5FM-k6Fh5oX2n59rw9g=s88-c-k-c0x00ffffff-no-rj\"\n      },\n      \"title\": \"How To Manage Your Money (50/30/20 Rule)\",\n      \"views\": 2322651,\n      \"upload\": \"2019-05-13T18:30:00.000Z\"\n    }\n  },\n  \"subd\": [\n    \"zachstar\",\n    \"kurz\",\n    \"fineart\",\n    \"melodysheep\",\n    \"tseries\",\n    \"teded\",\n    \"soham\"\n  ],\n  \"channels\": {\n    \"zachstar\": {\n      \"name\": \"Zach Star\",\n      \"pfp\": \"zach.jpg\"\n    },\n    \"kurz\": {\n      \"name\": \"Kurzgesagt – In a Nutshell\",\n      \"pfp\": \"kurz.jpg\"\n    },\n    \"fineart\": {\n      \"name\": \"Fine Art Academy\",\n      \"pfp\": \"fineart.jpg\"\n    },\n    \"melodysheep\": {\n      \"name\": \"melodysheep\",\n      \"pfp\": \"melodysheep.jpg\"\n    },\n    \"tseries\": {\n      \"name\": \"T-Series\",\n      \"pfp\": \"https://yt3.ggpht.com/DzaZaTX6gdgjjPI_vkNc2dPbI794UroI9fTAunua0fa7lukDj5NDkjfhS5-w2KXuvXS02r92=s88-c-k-c0x00ffffff-no-rj\"\n    },\n    \"teded\": {\n      \"name\": \"TED-Ed\",\n      \"pfp\": \"https://yt3.ggpht.com/HjXKmDGoAp6b-JdGYpqJYYeN4S_CMpD_kqWvldpN53cbzn-i73t6mVNo8mNki-xLPwi0BVSFi-o=s88-c-k-c0x00ffffff-no-rj\"\n    },\n    \"soham\": {\n      \"name\": \"Soham Das\",\n      \"pfp\": \"https://yt3.ggpht.com/ytc/AKedOLQp8wKnJY5r7z9fqdSikiVX48DxBXcKCGsfPJ0DGBM=s88-c-k-c0x00ffffff-no-rj\"\n    }\n  }\n}\n"
  },
  {
    "path": "src/store/actions/index.js",
    "content": "import store from 'store';\nimport apps from './data/apps';\nimport {\n  favbar,\n  page1apps,\n  page2bar,\n  page2apps,\n  page3apps,\n  page1wid,\n  page2wid,\n  page3wid,\n  page4wid\n} from './data/preset';\nimport axios from 'axios';\nimport './prototypes.js';\n\nimport whatsapp_data from './data/whatsapp.json';\nimport youtube_data from './data/youtube.json';\n\nconst {round, floor, random, min, max, abs} = Math;\n\nexport const gene_name = (x=10) => random().toString(36).substring(2, x).toLowerCase()\nexport const srandom = (seed)=>{\n  var x = Math.sin(seed++) * 10000\n  return x - Math.floor(x)\n}\n\nexport const shuffle = (arr, seed)=>{\n  var m = arr.length, t, i\n  while (m) {\n    i = Math.floor(srandom(seed) * m--)\n    t = arr[m]\n    arr[m] = arr[i]\n    arr[i] = t\n    ++seed\n  }\n\n  return arr\n}\n\nexport const dispatchAction = (e) => {\n  var action = {\n    type: e.target.dataset.action,\n    payload: e.target.dataset.payload,\n  };\n\n  if (action.type) store.dispatch(action);\n}\n\nexport const dispatchAct = (action) => {\n  if(action.type) store.dispatch(action);\n}\n\nexport const openAppPage = (id, page) => {\n  dispatchAct({type: \"home/navApp\", payload: page})\n  setTimeout(()=> dispatchAct({\n    type: \"home/openApp\",\n    payload: id\n  }), 200)\n}\n\nexport const fetchBatteryStatus = () => {\n  try{\n    var battery = navigator.getBattery()\n    if(battery){\n      battery.then((battery) => {\n        store.dispatch({\n          type: \"global/battery\",\n          payload: {\n            charging: battery.charging,\n            level: battery.level,\n          },\n        })\n      })\n    }\n  }catch(e){\n\n  }\n}\n\nexport const fillZero = (x)=>{\n  return (x<9?\"0\":\"\") + x\n}\n\nconst fetchTime = () => {\n  var date = new Date();\n  var timestring = date.toLocaleTimeString(\"en-US\", {\n    hour: \"numeric\",\n    minute: \"numeric\",\n    hour12: !store.getState().global.time.military,\n  }).split(\" \")\n\n  timestring[0] = timestring[0].split(\":\")\n\n  store.dispatch({type: \"global/time\", payload: {\n    hours: timestring[0][0],\n    minutes: timestring[0][1],\n    abb: timestring[1]\n  }})\n\n  store.dispatch({type: \"global/date\", payload: {\n    day: date.getDate(), month: date.getMonth(), year: date.getFullYear()\n  }})\n}\n\nconst fetchActions = () => {\n  fetchBatteryStatus();\n  fetchTime();\n}\n\nexport const fetchWeather = () => {\n  var defaultData = {\n    city: \"New york\",\n    temperature: \"32\",\n    icon: \"c\",\n    predictions: [\n      {\n        date: \"2020-01-01\",\n        day: \"Mon\",\n        temperature: \"33\",\n        icon: \"lr\"\n      },{\n        date: \"2020-01-02\",\n        day: \"Tue\",\n        temperature: \"34\",\n        icon: \"t\"\n      },{\n        date: \"2020-01-03\",\n        day: \"Wed\",\n        temperature: \"35\",\n        icon: \"lc\"\n      },{\n        date: \"2020-01-04\",\n        day: \"Thu\",\n        temperature: \"36\",\n        icon: \"hr\"\n      }\n    ]\n  }\n\n  var geocodingapi = \"https://api.techniknews.net/ipgeo/\",\n      weatherapi = \"https://www.metaweather.com/api/location\"\n\n  if(true) return\n\n  axios.get(geocodingapi).then(res => res.data).then((res) => {\n    defaultData.city = res.regionName + \", \" + res.country\n    var woeidurl = weatherapi + `/search/?lattlong=${res.lat},${res.lon}`\n    console.log(woeidurl);\n    axios.get(woeidurl, {\n      \"mode\": \"no-cors\",\n      withCredentials: false\n    }).then(res => res.data).then(res => {\n      console.log(res);\n      if(res && res[0]){\n        var weatherurl = weatherapi + \"/\" + res[0].woeid\n        console.log(weatherurl);\n        // axios.get(weatherurl).then(res => res.data).then(res => {\n          // console.log(res);\n        // })\n      }\n    })\n  }).catch(e => e)\n}\n\nexport const loadSettings = () => {\n  fetchActions()\n  loadApps()\n  fetchWeather()\n  const shortUpdates = setInterval(fetchActions, 10000);\n  window.onresize = ()=>{\n    store.dispatch({type: \"global/resolution\", payload: {\n      width: window.innerWidth,\n      height: window.innerHeight\n    }})\n  }\n}\n\nexport const loadApps = ()=>{\n  var tmp = {}\n  for (var i = 0; i < apps.length; i++) {\n    tmp[apps[i].icon] = apps[i]\n  }\n\n  store.dispatch({type: \"home/setApps\", payload: tmp});\n  store.dispatch({type: \"home/setFavBar\", payload: favbar});\n\n  var homelist = {}\n  // page 1\n  for (var i = 0; i < page1apps.length; i++) {\n    homelist[page1apps[i].icon] = {\n      page: 1,\n      type: 'app',\n      row: [6,7],\n      col: [i+1,i+2]\n    }\n  }\n\n  // adding home screen widgets\n  for (var i = 0; i < page1wid.length; i++) {\n    homelist[gene_name()] = {\n      page: 1,\n      type: 'widget',\n      row: page1wid[i].slice(0,2),\n      col: page1wid[i].slice(2,4),\n      widget: page1wid[i][4]\n    }\n  }\n\n  // page 2\n  for (var i = 0; i < page2apps.length; i++) {\n    homelist[page2apps[i].icon] = {\n      page: 2,\n      type: 'app',\n      row: [floor(i/4) + 1, floor(i/4) + 2],\n      col: [(i%4)+1,(i%4)+2]\n    }\n  }\n\n  // page 2 bar\n  for (var i = 0; i < page2bar.length; i++) {\n    homelist[page2bar[i].icon] = {\n      page: 2,\n      type: 'app',\n      row: [6, 7],\n      col: [(i%4)+1,(i%4)+2]\n    }\n  }\n\n  // page 2 widgets\n  for (var i = 0; i < page2wid.length; i++) {\n    homelist[gene_name()] = {\n      page: 2,\n      type: 'widget',\n      row: page2wid[i].slice(0,2),\n      col: page2wid[i].slice(2,4),\n      widget: page2wid[i][4]\n    }\n  }\n\n  // page 3\n  for (var i = 0; i < page3apps.length; i++) {\n    homelist[page3apps[i].icon] = {\n      page: 3,\n      type: 'app',\n      row: [floor(i/4) + 1, floor(i/4) + 2],\n      col: [(i%4)+1,(i%4)+2]\n    }\n  }\n\n  // page 3 widgets\n  for (var i = 0; i < page3wid.length; i++) {\n    homelist[gene_name()] = {\n      page: 3,\n      type: 'widget',\n      row: page3wid[i].slice(0,2),\n      col: page3wid[i].slice(2,4),\n      widget: page3wid[i][4]\n    }\n  }\n\n  // page 4 widgets\n  for (var i = 0; i < page4wid.length; i++) {\n    homelist[gene_name()] = {\n      page: 4,\n      type: 'widget',\n      row: page4wid[i].slice(0,2),\n      col: page4wid[i].slice(2,4),\n      widget: page4wid[i][4]\n    }\n  }\n\n  Object.keys(homelist).forEach((key, i) => {\n    store.dispatch({type: \"home/setSlide\", payload: {\n      id: key,\n      data: homelist[key]\n    }});\n  });\n\n  loadWhatsApp()\n  loadYouTube()\n}\n\nconst randomTimes = (c = 1, b = 60, f = 60)=>{\n  var tmptime = new Date(new Date() - round(random()*b)*60*1000),\n      arr = []\n\n  while(c>0){\n    arr.push(tmptime)\n    tmptime = new Date(tmptime - round(random()*f)*60*1000)\n    c -= 1\n  }\n\n  return arr\n}\n\nconst loadWhatsApp = ()=>{\n  var tmp = {...whatsapp_data};\n  tmp.curr = 0;\n\n  var tmptimes = randomTimes(tmp.self.status.length).reverse()\n  for (var i = tmp.self.status.length - 1; i>=0; i--) {\n    tmp.self.status[i].time = tmptimes[i].toISOString()\n  }\n\n  for (var i = 0; i < tmp.chats.length; i++) {\n    var cont = tmp.chats[i]\n    cont.id = i\n\n    if(cont.status){\n      var tdates = randomTimes(cont.chat.length,720,20).reverse()\n      for (var j = cont.status.length - 1; j >= 0; j--) {\n        cont.status[j].time = tdates[j].toISOString()\n      }\n    }else cont.status = []\n\n\n    if(cont.chat){\n      var tdates = randomTimes(cont.chat.length,60,300).reverse(),\n          replied = false;\n\n      for (var j = cont.chat.length - 1; j >= 0; j--) {\n        cont.chat[j].time = tdates[j].toISOString()\n        if(cont.chat[j].type==\"2\"){\n          cont.chat[j].seen = (j+1 == cont.chat.length) && !replied ?\n                                floor(random()*3) : 2;\n        }else replied = true\n      }\n    }else cont.chat = []\n\n    tmp.chats[i] = {...cont};\n  }\n\n  tmp.media = {}\n  tmp.status = {\n    vis: !true,\n    id: -1\n  }\n\n  store.dispatch({type: 'whatsapp/setData', payload: tmp});\n}\n\nconst loadYouTube = ()=>{\n  var tmp = {...youtube_data}\n\n  tmp.watch = {}\n  tmp.comp = false\n\n  Object.keys(tmp.channels).forEach((key, i) => {\n    var chnl = {...tmp.channels[key]}\n    chnl.id = key\n    tmp.channels[key] = {...chnl}\n  })\n\n  Object.keys(tmp.vids).forEach((key, i) => {\n    var ytvid = {...tmp.vids[key]}\n    ytvid.id = key\n    ytvid.views = Number(ytvid.views)\n    ytvid.likes = round(ytvid.views*(0.1 + random()*0.4))\n    ytvid.dislikes = round(ytvid.likes*(0.2 + random()*0.8))\n    if(!ytvid.thumb) ytvid.thumb = `https://i.ytimg.com/vi/${key}/hq720.jpg`\n    var channel\n    if(typeof(ytvid.channel)!=\"string\"){\n      channel = {...ytvid.channel}\n      channel.id = gene_name(8)\n      ytvid.channel = channel.id\n    }else channel = {...tmp.channels[ytvid.channel]}\n\n    if(!channel.subs) channel.subs = round(ytvid.views*(0.05 + random()*0.1))\n\n    tmp.channels[channel.id] = channel\n    tmp.vids[key] = {...ytvid}\n  })\n\n  // tmp.watch = {id: \"3izFMB91K_Q\"}\n  // tmp.comp = false\n\n  tmp.explore.trending = Object.keys(tmp.vids).sort(() => Math.random() - 0.5).splice(0,15)\n  tmp.home = Object.keys(tmp.vids).sort(() => Math.random() - 0.5)\n  tmp.library.hist = Object.keys(tmp.vids).filter((x,i) => i&1).splice(0,8)\n\n  store.dispatch({type: 'youtube/setData', payload: tmp});\n}\n"
  },
  {
    "path": "src/store/actions/prototypes.js",
    "content": "const {round, floor, random, min, max, abs} = Math;\n\nArray.prototype.remove = function(a) {\n  var idx = this.indexOf(a)\n  for (var i = idx; i < this.length - 1; i++) {\n    this[i] = this[i+1]\n  }\n\n  this.length -= 1\n}\n\nString.prototype.strip = function(c) {\n  var i = 0,\n    j = this.length - 1;\n  while (this[i] === c) i++;\n  while (this[j] === c) j--;\n  return this.slice(i, j + 1);\n}\n\nString.prototype.csum = function() {\n  return [...Array(this.length)].map((x,i) => this.charCodeAt(i)).reduce((a,b) => a+b)\n}\n\nString.prototype.reverse = function() {\n  return this.split('').reverse().join('')\n}\n\nString.prototype.count = function(c) {\n  var result = 0,\n    i = 0;\n  for (i; i < this.length; i++)\n    if (this[i] == c) result++;\n  return result;\n};\n\nString.prototype.capitalize = function() {\n  return this.charAt(0).toUpperCase() + this.slice(1);\n};\n\nNumber.prototype.quantf = function() {\n  if(this < 1000) return this + 1 - 1\n  else if(this < 1e6) return Math.floor(this/1000)+\"K\"\n  else if(this < 1e9) return Math.floor(this/1e5)/10 +\"M\"\n  else return Math.floor(this/1e8)/10 +\"B\"\n};\n\nDate.prototype.time12 = function() {\n  return this.toLocaleTimeString(\"en-US\", {\n    hour: \"numeric\",\n    minute: \"numeric\"\n  })\n};\n\nDate.prototype.time24 = function() {\n  return this.toLocaleTimeString(\"en-US\", {\n    hour: \"numeric\",\n    minute: \"numeric\",\n    hour12: false\n  })\n};\n\nDate.prototype.pastdate = function() {\n  if(this.toDateString() == new Date().toDateString()) return \"Today\"\n  else if (this.toDateString() == new Date(new Date() - 24*3600000).toDateString()) {\n    return \"Yesterday\"\n  }else{\n    return this.toLocaleDateString(\"en-US\", {\n      month: \"long\",\n      day: \"numeric\",\n      year: \"numeric\"\n    })\n  }\n};\n\nDate.prototype.minifyTime = function(t) {\n  if(!t) t = round((new Date() - this)/(60*1000))\n\n  if(t < 60) return `${t} min ago`\n  else{\n    var d = new Date(new Date() - t*60*1000),\n        timestr = d.pastdate() + ', '\n\n    timestr += d.time12()\n    return timestr\n  }\n}\n\nDate.prototype.minifyDate = function(t) {\n  if(!t) t = round((new Date() - this)/(60*1000))\n\n  if(t < 60) return `${t} min ago`\n  else if(t < 1440) return `${Math.floor(t/60)} hours ago`\n  else if(t < 43200) return `${Math.floor(t/1440)} days ago`\n  else if(t < 525600) return `${Math.floor(t/43200)} months ago`\n  else return `${Math.floor(t/525600)} years ago`\n}\n\nDate.prototype.pastdatetime = function() {\n  var timestr = \"\", cdate = new Date();\n  if(this.toDateString() == cdate.toDateString()) timestr = \"Today\"\n  else if (this.toDateString() == new Date(cdate - 24*36*1e5).toDateString()) {\n    timestr = \"Yesterday\"\n  }else if(this.getFullYear() == cdate.getFullYear()){\n    timestr = this.toLocaleDateString(\"en-US\", {\n      month: \"long\",\n      day: \"numeric\"\n    })\n  }else{\n    timestr = this.toLocaleDateString(\"en-US\", {\n      day: \"numeric\",\n      month: \"numeric\",\n      year: \"2-digit\"\n    })\n  }\n\n  timestr += \", \"\n  timestr += this.time12()\n\n  return timestr\n};\n"
  },
  {
    "path": "src/store/index.js",
    "content": "import { configureStore } from \"@reduxjs/toolkit\";\nimport thunk from \"redux-thunk\";\n\n// reducers who will be repsonsible for all the actions and state handling\nimport wallReducer from './reducers/wallpaper';\nimport quickpanelReducer from './reducers/quickpanel';\nimport globalReducer from \"./reducers/global\";\nimport homeReducer from \"./reducers/home\";\nimport widgetReducer from \"./reducers/widget\";\n\nimport WhatsAppReducer from './reducers/apps/whatsapp';\nimport YouTubeReducer from './reducers/apps/youtube';\n\nconst allReducers = {\n  wallpaper: wallReducer,\n  quickpanel: quickpanelReducer,\n  global: globalReducer,\n  home: homeReducer,\n  widget: widgetReducer,\n  whatsapp: WhatsAppReducer,\n  youtube: YouTubeReducer\n};\n\nconst store = configureStore({\n  reducer: allReducers,\n  middleware: [thunk]\n});\n\nexport default store;\n"
  },
  {
    "path": "src/store/reducers/apps/whatsapp.js",
    "content": "import { createSlice } from \"@reduxjs/toolkit\";\nvar initialState = {};\n\nconst closeExtras = (state, action) => {\n  if(action.type != 'home/closeAllApps' && action.payload != \"whatsapp\") return\n  state.media.vis = false\n  state.status.vis = false\n}\n\nconst WhatsApp = createSlice({\n  name: \"whatsapp\",\n  initialState: initialState,\n  reducers: {\n    setData: (state, action) => {\n      Object.keys(action.payload).forEach(key => {\n        state[key] = action.payload[key]\n      });\n    },\n    setProp: (state, action) => {\n      state[action.payload.key] = action.payload.value\n    },\n    setChatProp: (state, action) => {\n      const {id, key, value} = action.payload;\n      if(!id || !state.chats[id]) return\n      state.chats[id][key] = value\n\n    },\n    setMedia: (state, action) => {\n      if(action.payload) state.media = action.payload;\n      state.media.vis = true\n      // component variable that indicates the home goback action\n      // to not goback and just turn it off\n      state.comp = true\n    },\n    setStatus: (state, action) => {\n      state.status.vis = true\n      state.status.id = action.payload || -1;\n      state.comp = true\n    },\n    setViewStatus: (state, action) => {\n      var {id, count} = action.payload\n      if(id==-1) return\n\n      var contact = state.chats[id]\n      if(!contact) return\n\n      for (var i = 0; i < contact.status.length; i++) {\n        if(i<count) contact.status[i].seen = true\n        else break\n      }\n\n      state.chats[id] = {...contact}\n    },\n    sendMsg: (state, action) => {\n      var contact = {...state.chats[action.payload.id]}\n      if(!contact) return\n\n      contact.chat = contact.chat || []\n      var msg = {\n        type: \"2\",\n        msg: action.payload.msg,\n        media: action.payload.media,\n        src: action.payload.src,\n        seen: 1,\n        time: new Date().toISOString()\n      }\n\n      contact.chat.push(msg)\n      state.chats[action.payload.id].chat = contact.chat\n    }\n  },\n  extraReducers: {\n    'home/goBack': (state, action) => {\n      state.media.vis = false\n      state.status.vis = false\n      state.comp = false\n    },\n    'home/closeApp': closeExtras,\n    'home/closeAllApps': closeExtras\n  }\n});\n\nexport default WhatsApp.reducer;\n"
  },
  {
    "path": "src/store/reducers/apps/youtube.js",
    "content": "import { createSlice } from \"@reduxjs/toolkit\";\n\nvar initialState = {}\n\nconst YouTube = createSlice({\n  name: \"youtube\",\n  initialState: initialState,\n  reducers: {\n    setData: (state, action) => {\n      Object.keys(action.payload).forEach(key => {\n        state[key] = action.payload[key]\n      });\n    },\n    setProp: (state, action) => {\n      state[action.payload.key] = action.payload.value\n    },\n    watchVideo: (state, action) => {\n      state.watch.id = action.payload\n      state.comp = true\n    },\n    closeVid: (state, action) => {\n      state.watch.id = null\n      state.comp = false\n    },\n    toggleSub: (state, action) => {\n      if(state.subd.includes(action.payload)){\n        state.subd = state.subd.filter(x => x!= action.payload)\n      }else{\n        var tmp = [...state.subd]\n        tmp.push(action.payload)\n        state.subd = [...tmp]\n      }\n    }\n  },\n  extraReducers: {\n    'home/goBack': (state, action) => {\n      state.comp = false\n    }\n  }\n});\n\nexport default YouTube.reducer;\n"
  },
  {
    "path": "src/store/reducers/global.js",
    "content": "import { createSlice } from \"@reduxjs/toolkit\";\n\nconst initialState = {\n  time: {\n    hours: 0,\n    minutes: 0,\n    abb: \"\",\n    military: false\n  },\n  date: {\n    day: 1,\n    month: 0,\n    year: 1970\n  },\n  battery: {\n    charging: false,\n    level: 1,\n  },\n  display: {\n    width: window.innerWidth,\n    height: window.innerHeight\n  }\n};\n\nconst Global = createSlice({\n  name: \"global\",\n  initialState: initialState,\n  reducers: {\n    battery: (state, action) => {\n      state.battery = action.payload;\n    },\n    time: (state, action) => {\n      state.time.hours = action.payload.hours;\n      state.time.minutes = action.payload.minutes;\n      state.time.abb = action.payload.abb;\n    },\n    date: (state, action) => {\n      state.date = action.payload;\n    },\n    resolution: (state, action) => {\n      state.display.width = action.payload.width;\n      state.display.height = action.payload.height;\n    }\n  },\n});\n\nexport default Global.reducer;\n"
  },
  {
    "path": "src/store/reducers/home.js",
    "content": "import { createSlice } from \"@reduxjs/toolkit\";\n\nvar initialState = {\n  slides: {\n    count: 4,\n    list: {}\n  },\n  apps: {},\n  stack: [],\n  ishome: true,\n  recent: false,\n  favbar: []\n};\n\nvar dev = \"\"\nif(process.env.REACT_APP_ENV==\"development\" && dev!=\"\"){\n  initialState.stack.push(dev)\n  initialState.ishome = false\n}\n\nconst searchpath = (tree, page, path=\"-\")=>{\n  var t_path = null;\n  if(path.includes(\"-\" + page + \"-\")) return path\n\n  Object.keys(tree).forEach(key => {\n    t_path = t_path || searchpath(tree[key], page, path + key + \"-\")\n  });\n\n  return t_path\n}\n\nconst Home = createSlice({\n  name: \"home\",\n  initialState: initialState,\n  reducers: {\n    setApps: (state, action) => {\n      state.apps = action.payload\n    },\n    setApp: (state, action) => {\n      if(state.apps[action.payload.id]){\n        state.apps[action.payload.id] = action.payload.data\n      }\n    },\n    setAppKey: (state, action) => {\n      var {id, key, value} = action.payload;\n      if(state.apps[id]){\n        state.apps[id][key] = value\n      }\n    },\n    navApp: (state, action) => {\n      var [id, page] = action.payload.split(\".\"),\n          tmp_path = searchpath({...state.apps[id].pagetree}, page)\n\n      if(tmp_path){\n        state.apps[id].path = tmp_path.strip(\"-\").split(\"-\")\n      }\n    },\n    goBack: (state, action) => {\n      if(state.ishome || state.recent || !state.stack.length) return\n      var cr_app = state.stack.at(-1),\n          tmp = {...state.apps[cr_app]}\n      if(tmp.comp) return\n\n      if(tmp.path && tmp.path.length){\n        if(tmp.path.length==1){ // set home\n          state.ishome = true\n          state.recent = false\n        }else{\n          tmp.path.pop()\n          state.apps[cr_app] = {...tmp}\n        }\n      }\n    },\n    setSlide: (state, action) => {\n      state.slides.list[action.payload.id] = action.payload.data\n    },\n    setFavBar: (state, action) => {\n      state.favbar = action.payload\n    },\n    setHome: (state, action) => {\n      state.ishome = true\n      state.recent = false\n    },\n    setRecent: (state, action) => {\n      state.recent = true\n      state.ishome = true\n    },\n    closeRecent: (state, action) => {\n      state.recent = false\n      state.ishome = true\n    },\n    openLink: (state, action) => {\n      window.open(action.payload, '_blank')\n    },\n    openApp: (state, action) => {\n      if(!action.payload) return;\n\n      var tmp = [...state.stack]\n      if(tmp.includes(action.payload)){\n        tmp.remove(action.payload)\n      }\n\n      tmp.push(action.payload)\n      state.stack = [...tmp]\n      state.ishome = false\n      state.recent = false\n    },\n    closeApp: (state, action) => {\n      if(!action.payload) return;\n\n      var tmp = [...state.stack]\n      if(tmp.includes(action.payload)){\n        tmp.remove(action.payload)\n        if(state.apps[action.payload]){\n          state.apps[action.payload].comp = false\n          state.apps[action.payload].path = ['main']\n        }\n      }\n\n      state.stack = [...tmp]\n    },\n    closeAllApps: (state, action) => {\n      var tmp = []\n\n      for (var i = 0; i < state.stack.length; i++) {\n        state.apps[state.stack[i]].comp = false\n        state.apps[state.stack[i]].path = ['main']\n      }\n\n      state.stack = [...tmp]\n      state.ishome = true\n      state.recent = false\n    }\n  },\n});\n\nexport default Home.reducer;\n"
  },
  {
    "path": "src/store/reducers/quickpanel.js",
    "content": "import {\n  createSlice\n} from \"@reduxjs/toolkit\";\n\nconst intialState = {\n  open: false,\n  extended: false,\n  config: [{\n    name: \"Wifi\",\n    state: 1,\n    icon: \"Wifi\",\n  }, {\n    name: \"Mobile data\",\n    state: 1,\n    icon: \"SwapVert\",\n  }, {\n    name: \"Ring\",\n    state: 0,\n    icon: \"VolumeUp\",\n  }, {\n    name: \"Bluetooth\",\n    state: 0,\n    icon: \"Bluetooth\",\n  }, {\n    name: \"Silent\",\n    state: 0,\n    icon: \"NotificationsOff\",\n  }, {\n    name: \"Auto Rotate\",\n    state: 0,\n    icon: \"WifiProtectedSetup\",\n  }, {\n    name: \"Airplane\",\n    state: 0,\n    icon: \"AirplanemodeActive\",\n  }, {\n    name: \"Flash light\",\n    state: 0,\n    icon: \"FlashlightOn\",\n  }, {\n    name: \"Eye comfort\",\n    state: 0,\n    icon: \"Visibility\",\n  }, {\n    name: \"Power mode\",\n    state: 0,\n    icon: \"BatterySaver\",\n  }, {\n    name: \"Location\",\n    state: 0,\n    icon: \"LocationOn\",\n  }, {\n    name: \"Hotspot\",\n    state: 0,\n    icon: \"CellTower\",\n  }, {\n    name: \"Connect\",\n    state: 0,\n    icon: \"Phonelink\",\n  }, {\n    name: \"Do not disturb\",\n    state: 0,\n    icon: \"DoNotDisturbOn\",\n  }, {\n    name: \"Screen Lock\",\n    state: 0,\n    icon: \"Lock\",\n  }, {\n    name: \"Screenshot\",\n    state: 0,\n    icon: \"Screenshot\",\n  }, {\n    name: \"Switch Sim\",\n    state: 0,\n    icon: \"SimCardOutlined\",\n  }, {\n    name: \"Kid Space\",\n    state: 0,\n    icon: \"ChildCare\",\n  }],\n  lazy_bright: 100\n};\n\nconst QuickPanel = createSlice({\n  name: \"quickpanel\",\n  initialState: intialState,\n  reducers: {\n    open: (state, action) => {\n      state.open = true;\n    },\n    close: (state, action) => {\n      state.open = false;\n      state.extended = false;\n    },\n    toggle: (state, action) => {\n      state.open = !state.open;\n      if (!state.open) {\n        state.extended = false;\n      }\n    },\n    extend: (state, action) => {\n      state.open = true;\n      state.extended = true;\n    },\n    collapse: (state, action) => {\n      state.open = true;\n      state.extended = false;\n    },\n    toggleTool: (state, action) => {\n      if(state.config[action.payload]){\n        state.config[action.payload].state ^= 1\n      }\n    },\n    setLazyBright: (state, action) => {\n      state.lazy_bright = action.payload\n    }\n  },\n});\n\nexport default QuickPanel.reducer;\n"
  },
  {
    "path": "src/store/reducers/wallpaper.js",
    "content": "import {createSlice} from '@reduxjs/toolkit';\n\nconst walls = [\"default.jpg\"]\nconst intialState = {wps: 0,src: walls[0]}\n\nconst wallSlice = createSlice({\n  name: \"wallaper\",\n  initialState: intialState,\n  reducers: {\n    setWall: (state, action) => {\n      state.src = action.payload\n    },\n    setWps: (state, action) => {\n      state.wps = action.payload\n      state.src = walls[action.payload]\n    }\n  }\n})\n\nexport default wallSlice.reducer;\n"
  },
  {
    "path": "src/store/reducers/widget.js",
    "content": "import { createSlice } from \"@reduxjs/toolkit\";\n\nconst initialState = {\n  weather: {\n    city: \"New york\",\n    temperature: \"32\",\n    icon: \"c\",\n    predictions: [\n      {\n        date: \"2020-01-01\",\n        day: \"Mon\",\n        temperature: \"33\",\n        icon: \"lr\"\n      },{\n        date: \"2020-01-02\",\n        day: \"Tue\",\n        temperature: \"34\",\n        icon: \"t\"\n      },{\n        date: \"2020-01-03\",\n        day: \"Wed\",\n        temperature: \"35\",\n        icon: \"lc\"\n      },{\n        date: \"2020-01-04\",\n        day: \"Thu\",\n        temperature: \"36\",\n        icon: \"hr\"\n      }\n    ]\n  }\n};\n\nconst Widget = createSlice({\n  name: \"widget\",\n  initialState: initialState,\n  reducers: {\n    weather: (state, action) => {\n      state.weather = action.payload;\n    }\n  },\n});\n\nexport default Widget.reducer;\n"
  },
  {
    "path": "src-tauri/.gitignore",
    "content": "# Generated by Cargo\n# will have compiled files and executables\n/target/\nWixTools\n"
  },
  {
    "path": "src-tauri/Cargo.toml",
    "content": "[package]\nname = \"app\"\nversion = \"0.1.0\"\ndescription = \"A Tauri App\"\nauthors = [\"you\"]\nlicense = \"\"\nrepository = \"\"\ndefault-run = \"app\"\nedition = \"2021\"\nrust-version = \"1.57\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[build-dependencies]\ntauri-build = { version = \"1.0.0-rc.8\", features = [] }\n\n[dependencies]\nserde_json = \"1.0\"\nserde = { version = \"1.0\", features = [\"derive\"] }\ntauri = { version = \"1.0.0-rc.9\", features = [\"api-all\", \"system-tray\", \"updater\"] }\n\n[features]\n# by default Tauri runs in production mode\n# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL\ndefault = [ \"custom-protocol\" ]\n# this feature is used used for production builds where `devPath` points to the filesystem\n# DO NOT remove this\ncustom-protocol = [ \"tauri/custom-protocol\" ]\n"
  },
  {
    "path": "src-tauri/build.rs",
    "content": "fn main() {\n  tauri_build::build()\n}\n"
  },
  {
    "path": "src-tauri/src/main.rs",
    "content": "#![cfg_attr(\n  all(not(debug_assertions), target_os = \"windows\"),\n  windows_subsystem = \"windows\"\n)]\n\nfn main() {\n  tauri::Builder::default()\n    .run(tauri::generate_context!())\n    .expect(\"error while running tauri application\");\n}\n"
  },
  {
    "path": "src-tauri/tauri.conf.json",
    "content": "{\n  \"$schema\": \"..\\\\node_modules/@tauri-apps/cli\\\\schema.json\",\n  \"build\": {\n    \"beforeBuildCommand\": \"\",\n    \"beforeDevCommand\": \"\",\n    \"devPath\": \"http://localhost:3000\",\n    \"distDir\": \"../build\"\n  },\n  \"package\": {\n    \"productName\": \"Android11React\",\n    \"version\": \"0.0.3\"\n  },\n  \"tauri\": {\n    \"allowlist\": {\n      \"all\": true\n    },\n    \"bundle\": {\n      \"active\": true,\n      \"category\": \"DeveloperTool\",\n      \"copyright\": \"\",\n      \"deb\": {\n        \"depends\": []\n      },\n      \"externalBin\": [],\n      \"icon\": [\n        \"icons/32x32.png\",\n        \"icons/128x128.png\",\n        \"icons/128x128@2x.png\",\n        \"icons/icon.icns\",\n        \"icons/icon.ico\"\n      ],\n      \"identifier\": \"com.blueedge.androidreact\",\n      \"longDescription\": \"\",\n      \"macOS\": {\n        \"entitlements\": null,\n        \"exceptionDomain\": \"\",\n        \"frameworks\": [],\n        \"providerShortName\": null,\n        \"signingIdentity\": null\n      },\n      \"resources\": [],\n      \"shortDescription\": \"\",\n      \"targets\": \"all\",\n      \"windows\": {\n        \"certificateThumbprint\": null,\n        \"digestAlgorithm\": \"sha256\",\n        \"timestampUrl\": \"\"\n      }\n    },\n    \"security\": {\n      \"csp\": null\n    },\n    \"updater\": {\n      \"active\": true,\n      \"endpoints\": [\n        \"https://github.win11react.com/update/android/\"\n    ],\n    \"dialog\": true,\n    \"pubkey\": \"dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDY1QzY4RkFENDQ3RDY2RDEKUldUUlpuMUVyWS9HWlY2RVVlTlU3OHpOSThOQUN1Vi95VWxvVFZ1dEYzZUxUUlJPWGdYMDFuRWsK\"  \n    },\n    \"windows\": [\n      {\n        \"fullscreen\": false,\n        \"height\": 600,\n        \"resizable\": true,\n        \"title\": \"Android11React\",\n        \"width\": 800\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "module.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n}\n"
  },
  {
    "path": "timeline.md",
    "content": "## The major problems I faced during the development\n\n(ps: This is just the tip of iceberg)\n\n##### How do you change apps?\n  - either hide them all at once and show one of them when called\n\n  or\n\n  - use a long slider with all apps and scroll (or rather snap) it accordingly\n     on demand (✔️)\n\n##### So the problem is how to statically order the apps without losing the state in the Swiper\n  - Make your own swiper ??\n  - Use Iframe and router\n  - Somehow ?\n\n**sol**: render them separately (the apps and recent menu)\n\n##### This weird bug when stack array is being changed, it transfers the state\n  - yeah, because that is what happens when you dynamically change the array in react, dumbass\n\n  - to fix the CSS tranlateUp transition, I used animation instead of transition\n\n  - to make it more fruitful, I manually handled the scrolls and gave up on the last item\n\n##### How do you make the glimpse of apps appear in the recent menu without breaking the whole thing\n  - duplicate the innerHTML\n\n  - make sure to handle the react states properly\n\n  - I had to disable the lazy component for that to work (¬_¬\")\n\n##### Sometime the bottom nav back button should not revoke back action in few cases\n  For any certain apps like media opened in case of whatsApp, it need to be handled\n  not by pagination of components. So how do you accommodate this without breaking\n  the current navigation system?\n\n  **sol**: Make a common value that tells the global back action handler to skip this\n     call and listen it in the custom app reducer by using extraReducers properties\n     of @redux/toolkit\n\n##### How to reiterate the previous state of the app when collapsed?\n  - Either use a separate reducer for that app\n\n  or\n\n  - if the requirement is small make the changes in the main apps reducer\n\n##### How to transition between pages of an app without have to repeat the same code for every app\n  - Make a navigation system with predefined path and fetch the page state for each app accordingly\n    - I know! I made it sound easier XD\n\n##### Now the problem with nav system is that it is declaring the app pagetree when the app is opened first time\ni.e it need to be opened atleast once before getting called to open from externally.\n\nThe problem with this is that apps like google can be opened by a widget and user should be able to open the app from widget before opening from app icon\n\n  - The simplest solution is to manually trigger the openApp action before triggering navapp action, everytime. (¬_¬ )\n\n  - Another is to call the openApp action from navApp\n  action once for all\n      - The problem with solution is that there won't be    any buffer time for the app to open and define its pagetree, rendering the navapp action useless (╯°□°）╯︵ ┻━┻\n\n**sol** : Make an action that first opens the app and then triggers the navApp action\n     with some delay (⌐■_■), Hotel ? Trivago ...\n"
  }
]