1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <!-- Google Tag Manager --> 5
5<script>
vendor: 323 bytes, line 5
5(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','
5GTM-WMB2TZX
vendor: 3 bytes, line 5
5');
5</script>
5 6 <!-- End Google Tag Manager --> 7 8 <meta charset="UTF-8"> 9 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 10 <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> 11 <link rel="preconnect" href="https://fonts.googleapis.com"> 12 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 13 <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800;900&family=Mulish:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet"> 14 <title>AVS4YOU Plugins Marketplace</title> 15 <style> 16 :root { 17 --accent: #1577e0; 18 --accent-dark: #1463c4; 19 --bg: #f4f7fb; 20 --panel: #ffffff; 21 --line: #e1e9f2; 22 --line-soft: #e7edf4; 23 --text: #16202e; 24 --muted: #5b6b7e; 25 --faint: #8494a8; 26 --shadow: 0 2px 8px rgba(16, 32, 46, 0.06); 27 } 28 29 * { 30 box-sizing: border-box; 31 } 32 33 html, 34 body { 35 height: 100%; 36 overflow: hidden; 37 } 38 39 body { 40 margin: 0; 41 font-family: Mulish, "Segoe UI", Roboto, Arial, sans-serif; 42 color: var(--text); 43 background: var(--bg); 44 } 45 46 button, 47 input { 48 font: inherit; 49 } 50 51 button { 52 border: 0; 53 } 54 55 a { 56 color: inherit; 57 } 58 59 .app-shell { 60 height: 100vh; 61 display: flex; 62 background: var(--bg); 63 overflow: hidden; 64 } 65 66 .sidebar { 67 width: 250px; 68 flex: 0 0 250px; 69 display: flex; 70 flex-direction: column; 71 background: var(--panel); 72 border-right: 1px solid var(--line); 73 overflow-y: auto; 74 } 75 76 .brand { 77 padding: 18px 18px 16px; 78 line-height: 1; 79 } 80 81 .brand-title { 82 font-family: Manrope, Mulish, sans-serif; 83 font-size: 14.5px; 84 font-weight: 900; 85 } 86 87 .brand-subtitle { 88 margin-top: 3px; 89 color: var(--accent); 90 font-family: Manrope, Mulish, sans-serif; 91 font-size: 10px; 92 font-weight: 800; 93 letter-spacing: 1.2px; 94 text-transform: uppercase; 95 } 96 97 .rail-section { 98 padding: 6px 12px 0; 99 } 100 101 .rail-section + .rail-section { 102 padding-top: 18px; 103 } 104 105 .rail-title { 106 padding: 0 8px 8px; 107 color: #9aa8bc; 108 font-size: 10.5px; 109 font-weight: 800; 110 letter-spacing: 1px; 111 text-transform: uppercase; 112 } 113 114 .rail-button { 115 width: 100%; 116 display: flex; 117 align-items: center; 118 gap: 10px; 119 min-height: 38px; 120 padding: 9px 11px; 121 margin-bottom: 2px; 122 border-radius: 9px; 123 color: #46566b; 124 background: transparent; 125 font-size: 13.5px; 126 font-weight: 600; 127 cursor: pointer; 128 text-align: left; 129 } 130 131 .rail-button.active { 132 color: var(--accent-dark); 133 background: #eef4fc; 134 font-weight: 800; 135 } 136 137 .rail-button .rail-icon { 138 width: 20px; 139 height: 20px; 140 flex: 0 0 20px; 141 display: inline-flex; 142 align-items: center; 143 justify-content: center; 144 color: #9aa8bc; 145 font-size: 13px; 146 } 147 148 .rail-button.active .rail-icon { 149 color: var(--accent); 150 } 151 152 .rail-button .rail-label { 153 flex: 1; 154 min-width: 0; 155 overflow: hidden; 156 text-overflow: ellipsis; 157 white-space: nowrap; 158 } 159 160 .rail-count { 161 color: #a6b3c4; 162 font-family: "JetBrains Mono", "Courier New", monospace; 163 font-size: 10.5px; 164 font-weight: 700; 165 } 166 167 .rail-button.active .rail-count { 168 color: var(--accent); 169 } 170 171 .app-badge { 172 width: 20px; 173 height: 20px; 174 flex: 0 0 20px; 175 display: inline-flex; 176 align-items: center; 177 justify-content: center; 178 border-radius: 6px; 179 color: #fff; 180 font-family: Mulish, sans-serif; 181 font-size: 8.5px; 182 font-weight: 900; 183 letter-spacing: 0.3px; 184 } 185 .app-badge.app-icon { 186 object-fit: contain; 187 background: transparent; 188 } 189 190 191 .main { 192 height: 100vh; 193 min-width: 0; 194 flex: 1; 195 display: flex; 196 flex-direction: column; 197 overflow: hidden; 198 } 199 200 .toolbar { 201 min-height: 64px; 202 flex: 0 0 auto; 203 display: flex; 204 align-items: center; 205 gap: 14px; 206 padding: 14px 22px; 207 background: var(--panel); 208 border-bottom: 1px solid var(--line); 209 } 210 211 .heading { 212 min-width: 145px; 213 line-height: 1; 214 } 215 216 .heading-title { 217 font-size: 16px; 218 font-weight: 800; 219 } 220 221 .heading-subtitle { 222 margin-top: 5px; 223 color: var(--faint); 224 font-size: 11.5px; 225 font-weight: 600; 226 } 227 228 .toolbar-spacer { 229 flex: 1; 230 } 231 232 .search { 233 width: min(260px, 32vw); 234 height: 38px; 235 display: flex; 236 align-items: center; 237 gap: 8px; 238 padding: 0 13px; 239 border: 1px solid var(--line); 240 border-radius: 8px; 241 background: var(--bg); 242 } 243 244 .search span { 245 display: inline-flex; 246 align-items: center; 247 justify-content: center; 248 color: #9aa8bc; 249 } 250 251 .svg-icon { 252 width: 16px; 253 height: 16px; 254 display: block; 255 fill: none; 256 stroke: currentColor; 257 stroke-width: 2; 258 stroke-linecap: round; 259 stroke-linejoin: round; 260 } 261 262 .rail-icon .svg-icon { 263 width: 15px; 264 height: 15px; 265 } 266 267 .view-button .svg-icon { 268 width: 17px; 269 height: 17px; 270 } 271 272 .search input { 273 min-width: 0; 274 width: 100%; 275 border: 0; 276 outline: 0; 277 background: transparent; 278 color: var(--text); 279 font-size: 13.5px; 280 font-weight: 500; 281 } 282 283 .segmented { 284 flex: 0 0 auto; 285 display: flex; 286 gap: 3px; 287 padding: 3px; 288 border: 1px solid var(--line); 289 border-radius: 8px; 290 background: #f0f4f9; 291 } 292 293 .view-button { 294 width: 30px; 295 height: 30px; 296 display: inline-flex; 297 align-items: center; 298 justify-content: center; 299 border-radius: 7px; 300 background: transparent; 301 color: #9aa8bc; 302 font-size: 15px; 303 cursor: pointer; 304 } 305 306 .view-button.active { 307 background: #fff; 308 color: var(--accent); 309 box-shadow: 0 1px 3px rgba(16, 32, 46, 0.14); 310 } 311 312 .content { 313 flex: 1; 314 display: flex; 315 flex-direction: column; 316 overflow-y: auto;
317 padding: 20px 22px 26px; 318 } 319 320 .plugins { 321 flex: 0 0 auto; 322 display: grid; 323 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); 324 gap: 18px; 325 align-items: stretch; 326 } 327 328 .plugins.list { 329 display: flex; 330 flex-direction: column; 331 gap: 10px; 332 } 333 334 .plugin-card { 335 min-width: 0; 336 display: flex; 337 flex-direction: column; 338 overflow: hidden; 339 border: 1px solid var(--line-soft); 340 border-radius: 8px; 341 background: var(--panel); 342 box-shadow: var(--shadow); 343 } 344 345 .preview { 346 position: relative; 347 height: 158px; 348 overflow: hidden; 349 background: #0e1b2b; 350 } 351 352 .preview-bg, 353 .preview img { 354 position: absolute; 355 inset: 0; 356 } 357 358 .preview-bg { 359 z-index: 0; 360 } 361 362 .preview img { 363 z-index: 1; 364 width: 100%; 365 height: 100%; 366 object-fit: cover; 367 } 368 369 .preview img.icon-media { 370 width: 88px; 371 height: 88px; 372 margin: auto; 373 object-fit: contain; 374 } 375 376 .preview-badges { 377 position: absolute; 378 top: 11px; 379 left: 11px; 380 z-index: 2; 381 display: flex; 382 flex-direction: column; 383 align-items: flex-start; 384 gap: 6px; 385 } 386 387 .preview-ai { 388 position: absolute; 389 top: 11px; 390 right: 11px; 391 z-index: 2; 392 } 393 394 .badge { 395 display: inline-flex; 396 align-items: center; 397 gap: 4px; 398 height: 21px; 399 padding: 0 9px; 400 border-radius: 7px; 401 background: rgba(255, 255, 255, 0.92); 402 color: var(--accent-dark); 403 font-size: 10px; 404 font-weight: 800; 405 letter-spacing: 0.2px; 406 white-space: nowrap; 407 backdrop-filter: blur(4px); 408 } 409 410 .badge.key { 411 color: #b5701a; 412 } 413 414 .badge.ai { 415 background: rgba(15, 16, 30, 0.55); 416 color: #ffd9ae; 417 } 418 419 .dot { 420 width: 5px; 421 height: 5px; 422 border-radius: 999px; 423 background: #fda050; 424 } 425 426 .card-body { 427 flex: 1; 428 display: flex; 429 flex-direction: column; 430 gap: 9px; 431 padding: 15px 16px 16px; 432 } 433 434 .plugin-title { 435 margin: 0; 436 overflow: hidden; 437 color: var(--text); 438 font-size: 15.5px; 439 font-weight: 800; 440 text-overflow: ellipsis; 441 white-space: nowrap; 442 } 443 444 .plugin-desc { 445 margin: 0; 446 overflow: hidden; 447 display: -webkit-box; 448 -webkit-box-orient: vertical; 449 -webkit-line-clamp: 2; 450 color: var(--muted); 451 font-size: 12.5px; 452 font-weight: 500; 453 line-height: 1.5; 454 } 455 456 .card-bottom { 457 margin-top: auto; 458 display: flex; 459 align-items: center; 460 justify-content: space-between; 461 gap: 10px; 462 padding-top: 13px; 463 border-top: 1px solid #eef2f7; 464 } 465 466 .meta { 467 min-width: 0; 468 display: flex; 469 align-items: center; 470 gap: 8px; 471 flex-wrap: wrap; 472 } 473 474 .meta-text { 475 color: #9aa8bc; 476 font-family: "JetBrains Mono", "Courier New", monospace; 477 font-size: 10.5px; 478 font-weight: 600; 479 white-space: nowrap; 480 } 481 482 .platforms { 483 display: inline-flex; 484 gap: 2px; 485 padding: 2px; 486 border: 1px solid var(--line); 487 border-radius: 7px; 488 background: #f0f4f9; 489 } 490 491 .platform-chip { 492 padding: 3px 9px; 493 border-radius: 5px; 494 background: transparent; 495 color: var(--faint); 496 font-family: "JetBrains Mono", "Courier New", monospace; 497 font-size: 10px; 498 font-weight: 700; 499 cursor: pointer; 500 } 501 502 .platform-chip.active { 503 background: var(--accent); 504 color: #fff; 505 } 506 507 .download-btn { 508 height: 34px; 509 flex: 0 0 auto; 510 display: inline-flex; 511 align-items: center; 512 justify-content: center; 513 padding: 0 18px; 514 border-radius: 8px; 515 color: #fff; 516 background: linear-gradient(135deg, #2b9bf4, #1577e0); 517 box-shadow: 0 3px 8px rgba(21, 119, 224, 0.28); 518 font-size: 12.5px; 519 font-weight: 800; 520 text-decoration: none; 521 white-space: nowrap; 522 cursor: pointer; 523 } 524 525 .plugins.list .plugin-card { 526 min-height: 88px; 527 flex-direction: row; 528 align-items: center; 529 gap: 18px; 530 padding: 14px 18px; 531 } 532 533 .plugins.list .preview { 534 width: 60px; 535 height: 60px; 536 flex: 0 0 60px; 537 border-radius: 8px; 538 } 539 540 .plugins.list .preview-badges, 541 .plugins.list .preview-ai { 542 display: none; 543 } 544 545 .plugins.list .preview img.icon-media { 546 width: 100%; 547 height: 100%; 548 transform: scale(1.25); 549 } 550 551 .plugins.list .card-body { 552 min-width: 0; 553 flex: 1; 554 display: grid; 555 grid-template-columns: minmax(180px, 300px) minmax(160px, 1fr) auto; 556 align-items: center; 557 gap: 18px; 558 padding: 0; 559 } 560 561 .plugins.list .plugin-heading { 562 min-width: 0; 563 } 564 565 .plugins.list .plugin-title { 566 font-size: 15px; 567 } 568 569 .plugins.list .plugin-desc { 570 min-width: 0; 571 -webkit-line-clamp: 2; 572 } 573 574 .plugins.list .card-bottom { 575 flex: 0 0 auto; 576 flex-direction: column; 577 align-items: flex-end; 578 gap: 7px; 579 margin: 0; 580 padding: 0; 581 border: 0; 582 } 583 584 .empty { 585 flex: 1; 586 display: none; 587 text-align: center; 588 padding: 56px 20px; 589 } 590 591 .empty.visible { 592 display: block; 593 } 594 595 .empty h3 { 596 margin: 0; 597 color: var(--text); 598 font-size: 16px; 599 font-weight: 800; 600 } 601 602 .empty p { 603 margin: 7px 0 18px; 604 color: #62718a; 605 font-size: 13px; 606 } 607 608 .reset-btn { 609 height: 38px; 610 padding: 0 18px; 611 border-radius: 8px; 612 background: var(--accent); 613 color: #fff; 614 font-size: 13px; 615 font-weight: 700; 616 cursor: pointer; 617 } 618 619 .footer { 620 display: flex; 621 align-items: center; 622 justify-content: space-between; 623 gap: 16px; 624 margin: auto -22px -26px; 625 padding: 15px 22px; 626 border-top: 1px solid var(--line); 627 background: var(--panel); 628 } 629 630 .footer[hidden] { 631 display: none; 632 } 633 634 .footer.after-scroll { 635 margin-top: 34px; 636 } 637 638 .footer-note { 639 color: var(--faint); 640 font-size: 12px; 641 font-weight: 600; 642 } 643 644 .footer-links { 645 display: flex; 646 align-items: center; 647 gap: 16px; 648 font-size: 12.5px; 649 font-weight: 700; 650 } 651 652 .footer-links a { 653 color: var(--accent); 654 text-decoration: none; 655 } 656 657 .footer-sep { 658 width: 1px; 659 height: 13px; 660 background: #dce4ee; 661 } 662 663 .toast { 664 position: fixed; 665 right: 18px; 666 bottom: 18px; 667 z-index: 10; 668 max-width: min(420px, calc(100vw - 36px)); 669 padding: 12px 14px; 670 border-radius: 8px; 671 background: #16202e; 672 color: #fff; 673 box-shadow: 0 12px 30px rgba(15, 23, 42, 0.22); 674 font-size: 13px; 675 font-weight: 700; 676 opacity: 0; 677 transform: translateY(8px); 678 pointer-events: none; 679 transition: opacity 0.18s ease, transform 0.18s ease; 680 } 681 682 .toast.visible { 683 opacity: 1; 684 transform: translateY(0); 685 } 686 687 @media (max-width: 1080px) { 688 .plugins.list .card-body { 689 grid-template-columns: minmax(160px, 260px) minmax(140px, 1fr); 690 } 691 692 .plugins.list .card-bottom { 693 grid-column: 1 / -1; 694 flex-direction: row; 695 align-items: center; 696 justify-content: space-between; 697 } 698 } 699 700 @media (max-width: 900px) { 701 .toolbar { 702 flex-wrap: wrap; 703 gap: 10px; 704 } 705 706 .toolbar-spacer { 707 display: none; 708 } 709 710 .search { 711 order: 3; 712 width: 100%; 713 } 714 } 715 716 @media (max-width: 720px) { 717 .toolbar, 718 .content { 719 padding-left: 14px; 720 padding-right: 14px; 721 } 722 723 .plugins { 724 grid-template-columns: 1fr; 725 } 726 727 .plugins.list .plugin-card { 728 flex-direction: column; 729 align-items: stretch; 730 } 731 732 .plugins.list .preview { 733 width: 100%; 734 height: 120px; 735 flex-basis: auto; 736 } 737 738 .plugins.list .preview-badges, 739 .plugins.list .preview-ai { 740 display: flex; 741 } 742 743 .plugins.list .card-body { 744 display: flex; 745 flex-direction: column; 746 align-items: stretch; 747 gap: 9px; 748 } 749 750 .plugins.list .card-bottom { 751 padding-top: 13px; 752 border-top: 1px solid #eef2f7; 753 } 754 755 .footer { 756 align-items: flex-start; 757 flex-direction: column; 758 margin-left: -14px; 759 margin-right: -14px; 760 padding-left: 14px; 761 padding-right: 14px; 762 } 763 764 .footer-links { 765 flex-wrap: wrap; 766 gap: 10px; 767 } 768 769 .footer-sep { 770 display: none; 771 } 772 } 773 </style> 774</head> 775<body> 776 <!-- Google Tag Manager (noscript) -->
vendor: 70 bytes, lines 776-777
776 777 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
777GTM-WMB2TZX
vendor: 85 bytes, lines 777-778
777" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 778
778<!-- End Google Tag Manager (noscript) --> 779 <div class="app-shell" id="shell"> 780 <aside class="sidebar" aria-label="Marketplace filters"> 781 <div class="brand"> 782 <div class="brand-title">AVS4YOU</div> 783 <div class="brand-subtitle">Plugin Marketplace</div> 784 </div> 785 786 <div class="rail-section"> 787 <div class="rail-title">Categories</div> 788 <div id="categories"></div> 789 </div> 790 791 <div class="rail-section"> 792 <div class="rail-title">Applications</div> 793 <div id="apps"></div> 794 </div> 795 </aside> 796 797 <main class="main"> 798 <header class="toolbar"> 799 <div class="heading"> 800 <div class="heading-title" id="currentTitle">All plugins</div> 801 <div class="heading-subtitle" id="resultLabel">0 plugins available</div> 802 </div> 803 <div class="toolbar-spacer"></div> 804 <label class="search"> 805 <span aria-hidden="true" data-icon="search"></span> 806 <input id="search" type="search" placeholder="Search plugins..." autocomplete="off"> 807 </label> 808 <div class="segmented" aria-label="View"> 809 <button class="view-button active" id="gridView" type="button" title="Grid view" aria-label="Grid view"></button> 810 <button class="view-button" id="listView" type="button" title="List view" aria-label="List view"></button> 811 </div> 812 </header> 813 814 <section class="content"> 815 <div class="plugins" id="plugins"></div> 816 <div class="empty" id="empty"> 817 <h3>No plugins match</h3> 818 <p>Try another category, app, or search.</p> 819 <button class="reset-btn" id="reset" type="button">Reset filters</button> 820 </div> 821 <footer class="footer" id="footer"> 822 <div class="footer-note">All plugins are open source and available on GitHub</div> 823 <div class="footer-links"> 824 <a href="https://github.com/avs4you/avs4you.github.io" target="_blank" rel="noopener">View on GitHub</a> 825 <span class="footer-sep"></span> 826 <a href="docs">Documentation</a> 827 <span class="footer-sep"></span> 828 <a href="https://avs4you.com" target="_blank" rel="noopener">Visit AVS4YOU</a> 829 </div> 830 </footer> 831 </section> 832 </main> 833 </div> 834 <div class="toast" id="toast" role="status" aria-live="polite"></div> 835 836
836<script type="application/json" id="plugins-data"> 837[ 838 { 839 "slug": "effect-restoration-gaterv3", 840 "pluginId": "EffectGaterv3.plugin", 841 "name": "Restoration Gaterv3", 842 "desc": "A 1x restoration model for improving image quality, including noise, resizing, JPEG compression and mild blur.", 843 "apps": [ 844 "Image Converter", 845 "Video Converter", 846 "Video Editor" 847 ], 848 "version": "v1.0.0", 849 "type": "effect", 850 "typeLabel": "Image Effect", 851 "aiPowered": true, 852 "requiresKey": false, 853 "tint": "linear-gradient(135deg,#1FA85C,#0FB5C9)", 854 "media": "plugins/effect-restoration-gaterv3/Effect Restoration Gaterv3.gif", 855 "basePath": "plugins/effect-restoration-gaterv3", 856 "downloads": { 857 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-restoration-gaterv3-v1.0.0/effect-restoration-gaterv3-v1.0.0-x86.avsp", 858 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-restoration-gaterv3-v1.0.0/effect-restoration-gaterv3-v1.0.0-x64.avsp" 859 } 860 }, 861 { 862 "slug": "effect-spiral", 863 "pluginId": "EffectSpiral.plugin", 864 "name": "Effect Spiral", 865 "desc": "Dynamic spiral distortion with an outward explosion effect. Radial twist and expansion animations for stunning visuals.", 866 "apps": [ 867 "Video Converter", 868 "Video Editor" 869 ], 870 "version": "v1.0.1", 871 "type": "effect", 872 "typeLabel": "Image Effect", 873 "aiPowered": false, 874 "requiresKey": false, 875 "tint": "linear-gradient(135deg,#3B4FE0,#7C5CFF)", 876 "media": "plugins/effect-spiral/Effect Spiral.gif", 877 "basePath": "plugins/effect-spiral", 878 "downloads": { 879 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-spiral-v1.0.1/effect-spiral-v1.0.1-x86.avsp", 880 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-spiral-v1.0.1/effect-spiral-v1.0.1-x64.avsp" 881 } 882 }, 883 { 884 "slug": "effect-vhs", 885 "pluginId": "EffectVHS.plugin", 886 "name": "Effect VHS", 887 "desc": "Authentic VHS tape effect with noise, color degradation, tracking errors and chromatic aberration for a retro 80s-90s feel.", 888 "apps": [ 889 "Video Converter", 890 "Video Editor", 891 "Image Converter" 892 ], 893 "version": "v1.0.1", 894 "type": "effect", 895 "typeLabel": "Image Effect", 896 "aiPowered": false, 897 "requiresKey": false, 898 "tint": "linear-gradient(135deg,#E0398E,#7C2BD6)", 899 "media": "plugins/effect-vhs/Effect VHS.gif", 900 "basePath": "plugins/effect-vhs", 901 "downloads": { 902 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-vhs-v1.0.1/effect-vhs-v1.0.1-x86.avsp", 903 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-vhs-v1.0.1/effect-vhs-v1.0.1-x64.avsp" 904 } 905 }, 906 { 907 "slug": "heygen", 908 "pluginId": "heygen.plugin", 909 "name": "HeyGen AI Video Generator", 910 "desc": "The best online AI video generator and creator for professionals and marketers who value ease of use.", 911 "apps": [ 912 "Video Converter", 913 "Video Editor" 914 ], 915 "version": "v1.0.0", 916 "type": "content", 917 "typeLabel": "Content Plugin", 918 "aiPowered": true, 919 "requiresKey": true, 920 "tint": "linear-gradient(135deg,#FF9A2E,#F2552E)", 921 "media": "plugins/heygen/res/icons/app-icon.ico", 922 "basePath": "plugins/heygen", 923 "downloads": { 924 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/heygen-v1.0.0/heygen-v1.0.0-x86.avsp", 925 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/heygen-v1.0.0/heygen-v1.0.0-x64.avsp" 926 } 927 }, 928 { 929 "slug": "nano-banana", 930 "pluginId": "NanoBanana.plugin", 931 "name": "Nano Banana Image Generator", 932 "desc": "Generate, edit, ground, and iterate images with Google Nano Banana models through the Gemini API.", 933 "apps": [ 934 "Video Converter", 935 "Video Editor", 936 "Photo Editor" 937 ], 938 "version": "v1.0.0", 939 "type": "content", 940 "typeLabel": "Content Plugin", 941 "aiPowered": true, 942 "requiresKey": true, 943 "tint": "linear-gradient(135deg,#FFD33D,#22B8A8)", 944 "media": "plugins/nano-banana/icon.ico", 945 "basePath": "plugins/nano-banana", 946 "downloads": { 947 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/nano-banana-v1.0.0/nano-banana-v1.0.0-x86.avsp", 948 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/nano-banana-v1.0.0/nano-banana-v1.0.0-x64.avsp" 949 } 950 }, 951 { 952 "slug": "sora2", 953 "pluginId": "Sora2.plugin", 954 "name": "Sora2 Video Generator", 955 "desc": "AI-powered video generation using OpenAI's Sora 2 API. Create high-quality videos from text directly in your AVS workflow.", 956 "apps": [ 957 "Video Converter",
958 "Video Editor" 959 ], 960 "version": "v1.0.0", 961 "type": "content", 962 "typeLabel": "Content Plugin", 963 "aiPowered": true, 964 "requiresKey": true, 965 "tint": "linear-gradient(135deg,#0FB5C9,#1577E0)", 966 "media": "plugins/sora2/icon.ico", 967 "basePath": "plugins/sora2", 968 "downloads": { 969 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sora2-v1.0.0/sora2-v1.0.0-x86.avsp", 970 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sora2-v1.0.0/sora2-v1.0.0-x64.avsp" 971 } 972 }, 973 { 974 "slug": "stableaudio3", 975 "pluginId": "StableAudio3.plugin", 976 "name": "Stable Audio 3 Generator", 977 "desc": "Generate audio locally with Stable Audio 3 using CPU or NVIDIA CUDA acceleration.", 978 "apps": [ 979 "Audio Editor", 980 "Video Editor" 981 ], 982 "version": "v1.0.0", 983 "type": "content", 984 "typeLabel": "Content Plugin", 985 "aiPowered": true, 986 "requiresKey": false, 987 "tint": "linear-gradient(135deg,#6B5CE7,#2E9CCA)", 988 "media": "plugins/StableAudio3/icon.ico", 989 "basePath": "plugins/StableAudio3", 990 "downloads": { 991 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/stableaudio3-v1.0.0/stableaudio3-v1.0.0-x86.avsp", 992 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/stableaudio3-v1.0.0/stableaudio3-v1.0.0-x64.avsp" 993 } 994 }, 995 { 996 "slug": "sunoapi", 997 "pluginId": "SunoApi.plugin", 998 "name": "Suno API Music Generator", 999 "desc": "Generate songs, lyrics and sounds, extend or transform audio with Suno API.", 1000 "apps": [ 1001 "Audio Editor", 1002 "Audio Converter", 1003 "Video Editor", 1004 "Video Converter" 1005 ], 1006 "version": "v1.0.0", 1007 "type": "content", 1008 "typeLabel": "Content Plugin", 1009 "aiPowered": true, 1010 "requiresKey": true, 1011 "tint": "linear-gradient(135deg,#7C3AED,#EC4899)", 1012 "media": "plugins/sunoapi/icon.ico", 1013 "basePath": "plugins/sunoapi", 1014 "downloads": { 1015 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sunoapi-v1.0.0/sunoapi-v1.0.0-x86.avsp", 1016 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sunoapi-v1.0.0/sunoapi-v1.0.0-x64.avsp" 1017 } 1018 }, 1019 { 1020 "slug": "supertonic3", 1021 "pluginId": "Supertonic3.plugin", 1022 "name": "Supertonic 3 Text to Speech", 1023 "desc": "Generate natural multilingual speech locally with Supertonic 3 and ONNX Runtime directly in AVS Audio Editor and AVS Video Editor.", 1024 "apps": [ 1025 "Audio Editor", 1026 "Video Editor" 1027 ], 1028 "version": "v1.0.0", 1029 "type": "content", 1030 "typeLabel": "Content Plugin", 1031 "aiPowered": true, 1032 "requiresKey": false, 1033 "tint": "linear-gradient(135deg,#7756E8,#3478F6)", 1034 "media": "plugins/Supertonic3/icon.ico", 1035 "basePath": "plugins/Supertonic3", 1036 "downloads": { 1037 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/supertonic3-v1.0.0/supertonic3-v1.0.0-x86.avsp", 1038 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/supertonic3-v1.0.0/supertonic3-v1.0.0-x64.avsp" 1039 } 1040 }, 1041 { 1042 "slug": "veo3", 1043 "pluginId": "Veo3.plugin", 1044 "name": "Veo3 Video Generator", 1045 "desc": "AI-powered video creation with Google Veo 3. Turn your ideas into polished, cinematic clips from simple text prompts inside your AVS workflow.", 1046 "apps": [ 1047 "Video Converter", 1048 "Video Editor" 1049 ], 1050 "version": "v1.0.0", 1051 "type": "content", 1052 "typeLabel": "Content Plugin", 1053 "aiPowered": true, 1054 "requiresKey": true, 1055 "tint": "linear-gradient(135deg,#0FB5C9,#1577E0)", 1056 "media": "plugins/veo3/icon.ico", 1057 "basePath": "plugins/veo3", 1058 "downloads": { 1059 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/veo3-v1.0.0/veo3-v1.0.0-x86.avsp", 1060 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/veo3-v1.0.0/veo3-v1.0.0-x64.avsp" 1061 } 1062 }, 1063 { 1064 "slug": "youtube", 1065 "pluginId": "Youtube.plugin", 1066 "name": "YouTube Video Downloader", 1067 "desc": "Download video and audio from YouTube, Twitch and other sites supported by yt-dlp directly into your AVS workflow.", 1068 "apps": [ 1069 "Video Converter",
1070 "Video Editor" 1071 ], 1072 "version": "v1.0.0", 1073 "type": "content", 1074 "typeLabel": "Content Plugin", 1075 "aiPowered": false, 1076 "requiresKey": false, 1077 "tint": "linear-gradient(135deg,#FF0000,#CC0000)", 1078 "media": "plugins/youtube/icon.ico", 1079 "basePath": "plugins/youtube", 1080 "downloads": { 1081 "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/youtube-v1.0.0/youtube-v1.0.0-x86.avsp", 1082 "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/youtube-v1.0.0/youtube-v1.0.0-x64.avsp" 1083 } 1084 } 1085] 1086</script>
1086 1087 1088
1088<script> 1089 let PLUGINS = []; 1090 1091 const ICON_PLUGIN_BACKGROUND = "linear-gradient(135deg,#0FB5C9,#1577E0)"; 1092 const X86_ONLY = true; 1093 // Architectures come from the data (package.py writes plugin.downloads), 1094 // so adding one only means adding it to ARCHS in release.py. 1095 const DEFAULT_ARCH = "x86"; 1096 1097 const ICONS = { 1098 search: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>', 1099 grid: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg>', 1100 list: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M8 6h13M8 12h13M8 18h13"/><path d="M3 6h.01M3 12h.01M3 18h.01"/></svg>', 1101 all: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="3"/></svg>', 1102 ai: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2v4M12 18v4M2 12h4M18 12h4M4.9 4.9l2.8 2.8M16.3 16.3l2.8 2.8M19.1 4.9l-2.8 2.8M7.7 16.3l-2.8 2.8"/><circle cx="12" cy="12" r="3"/></svg>', 1103 effect: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m12 3 1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8L12 3Z"/><path d="m19 15 .8 2.2L22 18l-2.2.8L19 21l-.8-2.2L16 18l2.2-.8L19 15Z"/></svg>', 1104 content: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 5h16M4 12h16M4 19h16"/><path d="M8 5v14"/></svg>' 1105 }; 1106 1107 const CATEGORIES = [ 1108 { key: "all", label: "All plugins", icon: "all" }, 1109 { key: "ai", label: "AI Powered", icon: "ai" }, 1110 { key: "effect", label: "Effects", icon: "effect" }, 1111 { key: "content", label: "Content", icon: "content" } 1112 ]; 1113 1114 const APPS = [ 1115 { key: "all", label: "All apps", icon: "all" }, 1116 { key: "Video Converter", label: "AVS Video Converter", asset: "assets/AVSVideoConverter_Icon.png" }, 1117 { key: "Video Editor", label: "AVS Video Editor", asset: "assets/AVSVideoEditor_Icon.png" }, 1118 { key: "Image Converter", label: "AVS Image Converter", asset: "assets/AVSImageConverter_Icon.png" }, 1119 { key: "Audio Editor", label: "AVS Audio Editor", asset: "assets/AVSAudioEditor_Icon.png" }, 1120 { key: "Audio Converter", label: "AVS Audio Converter", asset: "assets/AVSAudioConverter_Icon.png" }, 1121 { key: "Video ReMaker", label: "AVS Video ReMaker", asset: "assets/AVSVideoReMaker_Icon.png" } 1122 ]; 1123 1124 function getAppLabel(appKey) { 1125 const app = APPS.find((item) => item.key === appKey); 1126 return app ? app.label : appKey; 1127 } 1128 1129 const params = new URLSearchParams(window.location.search); 1130 const typeParam = (params.get("type") || "").toLowerCase(); 1131 const typeAppFilter = { 1132 vc: "Video Converter", 1133 ve: "Video Editor", 1134 ic: "Image Converter", 1135 ae: "Audio Editor", 1136 ac: "Audio Converter", 1137 rm: "Video ReMaker" 1138 }; 1139 const initialAppFilter = typeAppFilter[typeParam] || "all"; 1140 const state = { 1141 isApp: typeParam === "app" || initialAppFilter !== "all", 1142 appPlatform: params.get("platform") || DEFAULT_ARCH, 1143 category: "all", 1144 app: initialAppFilter, 1145 search: "", 1146 view: "grid", 1147 platform: {} 1148 }; 1149 1150 const els = { 1151 brand: document.querySelector(".brand"), 1152 categories: document.getElementById("categories"), 1153 apps: document.getElementById("apps"), 1154 plugins: document.getElementById("plugins"), 1155 empty: document.getElementById("empty"), 1156 reset: document.getElementById("reset"), 1157 search: document.getElementById("search"), 1158 currentTitle: document.getElementById("currentTitle"), 1159 resultLabel: document.getElementById("resultLabel"), 1160 gridView: document.getElementById("gridView"), 1161 listView: document.getElementById("listView"), 1162 footer: document.getElementById("footer"), 1163 toast: document.getElementById("toast") 1164 }; 1165 1166 let toastTimer = null; 1167
1168 function renderStaticIcons() { 1169 els.gridView.innerHTML = ICONS.grid; 1170 els.listView.innerHTML = ICONS.list; 1171 document.querySelectorAll("[data-icon]").forEach((element) => { 1172 element.innerHTML = ICONS[element.dataset.icon] || ""; 1173 }); 1174 } 1175 1176 function loadPlugins() { 1177 const node = document.getElementById("plugins-data"); 1178 if (!node) throw new Error("Missing plugins-data"); 1179 PLUGINS = JSON.parse(node.textContent || "[]"); 1180 } 1181 1182 function matchCategory(plugin, category) { 1183 if (category === "all") return true; 1184 if (category === "effect") return plugin.type === "effect"; 1185 if (category === "ai") return plugin.aiPowered; 1186 if (category === "content") return plugin.type === "content"; 1187 return true; 1188 } 1189 1190 function getHref(plugin, platform) { 1191 // Absolute GitHub release links baked in by package.py, keyed by arch. 1192 const downloads = plugin.downloads || {}; 1193 return downloads[platform] || downloads[DEFAULT_ARCH] || ""; 1194 } 1195 1196 function getFilteredPlugins() { 1197 const query = state.search.trim().toLowerCase(); 1198 return PLUGINS.filter((plugin) => { 1199 if (!matchCategory(plugin, state.category)) return false; 1200 if (state.app !== "all" && !plugin.apps.includes(state.app)) return false; 1201 if (!query) return true; 1202 return ( 1203 plugin.name.toLowerCase().includes(query) || 1204 plugin.desc.toLowerCase().includes(query) || 1205 plugin.typeLabel.toLowerCase().includes(query) 1206 ); 1207 }); 1208 } 1209 1210 function makeButton(item, active, count, onClick) { 1211 const button = document.createElement("button"); 1212 button.type = "button"; 1213 button.className = "rail-button" + (active ? " active" : ""); 1214 button.addEventListener("click", onClick); 1215 1216 const icon = document.createElement(item.asset ? "img" : "span"); 1217 if (item.asset) { 1218 icon.className = "app-badge app-icon"; 1219 icon.src = item.asset; 1220 icon.alt = ""; 1221 icon.setAttribute("aria-hidden", "true"); 1222 } else { 1223 icon.className = "rail-icon"; 1224 icon.innerHTML = ICONS[item.icon] || ""; 1225 } 1226 1227 const label = document.createElement("span"); 1228 label.className = "rail-label"; 1229 label.textContent = item.label; 1230 1231 const counter = document.createElement("span"); 1232 counter.className = "rail-count"; 1233 counter.textContent = count; 1234 1235 button.append(icon, label, counter); 1236 return button; 1237 } 1238 1239 function renderFilters() { 1240 els.categories.replaceChildren(); 1241 CATEGORIES.forEach((item) => { 1242 const count = PLUGINS.filter((plugin) => matchCategory(plugin, item.key)).length; 1243 els.categories.appendChild(makeButton(item, state.category === item.key, count, () => { 1244 state.category = item.key; 1245 render(); 1246 })); 1247 }); 1248 1249 els.apps.replaceChildren(); 1250 APPS.forEach((item) => { 1251 const count = item.key === "all" 1252 ? PLUGINS.length 1253 : PLUGINS.filter((plugin) => plugin.apps.includes(item.key)).length; 1254 els.apps.appendChild(makeButton(item, state.app === item.key, count, () => { 1255 state.app = item.key; 1256 render(); 1257 })); 1258 }); 1259 } 1260 1261 function makeBadge(text, className) { 1262 const badge = document.createElement("span"); 1263 badge.className = "badge" + (className ? " " + className : ""); 1264 badge.textContent = text; 1265 return badge; 1266 } 1267 1268 function makeAiBadge() { 1269 const badge = makeBadge("AI", "ai"); 1270 const dot = document.createElement("span"); 1271 dot.className = "dot"; 1272 badge.prepend(dot); 1273 return badge; 1274 } 1275 1276 function makePlatformChips(plugin, activePlatform) { 1277 if (state.isApp || X86_ONLY) return null; 1278 1279 const wrap = document.createElement("span"); 1280 wrap.className = "platforms"; 1281 1282 Object.keys(plugin.downloads || {}).forEach((platform) => { 1283 const chip = document.createElement("button"); 1284 chip.type = "button"; 1285 chip.className = "platform-chip" + (platform === activePlatform ? " active" : ""); 1286 chip.textContent = platform; 1287 chip.addEventListener("click", () => { 1288 state.platform[plugin.slug] = platform; 1289 renderPlugins(); 1290 }); 1291 wrap.appendChild(chip); 1292 }); 1293 1294 return wrap; 1295 } 1296 1297 function showToast(message) { 1298 els.toast.textContent = message; 1299 els.toast.classList.add("visible"); 1300 clearTimeout(toastTimer); 1301 toastTimer = setTimeout(() => { 1302 els.toast.classList.remove("visible"); 1303 }, 2800); 1304 } 1305 1306 function handleAction(event, href) { 1307 if (!state.isApp) return; 1308 1309 event.preventDefault();
1310 try { 1311 if (window.chrome && window.chrome.webview) { 1312 window.chrome.webview.postMessage("download|" + href); 1313 } 1314 } catch (error) { 1315 // WebView messaging is only available inside the host application. 1316 } 1317 showToast("Install requested: " + href.split("/").pop()); 1318 } 1319 1320 function makeCard(plugin) { 1321 const activePlatform = state.isApp 1322 ? state.appPlatform 1323 : (X86_ONLY ? DEFAULT_ARCH : (state.platform[plugin.slug] || state.appPlatform)); 1324 const href = getHref(plugin, activePlatform); 1325 const card = document.createElement("article"); 1326 card.className = "plugin-card"; 1327 1328 const preview = document.createElement("div"); 1329 preview.className = "preview"; 1330 1331 const previewBg = document.createElement("div"); 1332 previewBg.className = "preview-bg"; 1333 previewBg.style.background = /\.ico$/i.test(plugin.media || "") 1334 ? ICON_PLUGIN_BACKGROUND 1335 : plugin.tint; 1336 preview.appendChild(previewBg); 1337 1338 if (plugin.media) { 1339 const image = document.createElement("img"); 1340 image.src = plugin.media; 1341 image.alt = plugin.name; 1342 if (/\.ico$/i.test(plugin.media)) image.className = "icon-media"; 1343 preview.appendChild(image); 1344 } 1345 1346 const badges = document.createElement("div"); 1347 badges.className = "preview-badges"; 1348 badges.appendChild(makeBadge(plugin.typeLabel)); 1349 if (plugin.requiresKey) badges.appendChild(makeBadge("API key", "key")); 1350 preview.appendChild(badges); 1351 1352 if (plugin.aiPowered) { 1353 const ai = document.createElement("div"); 1354 ai.className = "preview-ai"; 1355 ai.appendChild(makeAiBadge()); 1356 preview.appendChild(ai); 1357 } 1358 1359 const body = document.createElement("div"); 1360 body.className = "card-body"; 1361 1362 const heading = document.createElement("div"); 1363 heading.className = "plugin-heading"; 1364 1365 const title = document.createElement("h3"); 1366 title.className = "plugin-title"; 1367 title.textContent = plugin.name; 1368 heading.appendChild(title); 1369 1370 const desc = document.createElement("p"); 1371 desc.className = "plugin-desc"; 1372 desc.textContent = plugin.desc; 1373 1374 const bottom = document.createElement("div"); 1375 bottom.className = "card-bottom"; 1376 1377 const meta = document.createElement("div"); 1378 meta.className = "meta"; 1379 1380 const metaText = document.createElement("span"); 1381 metaText.className = "meta-text"; 1382 metaText.textContent = state.isApp 1383 ? activePlatform + " \u00b7 " + plugin.version 1384 : plugin.version; 1385 1386 const platformChips = makePlatformChips(plugin, activePlatform); 1387 meta.append(metaText); 1388 if (platformChips) meta.append(platformChips); 1389 1390 const link = document.createElement("a"); 1391 link.className = "download-btn"; 1392 link.href = state.isApp ? "#" : href; 1393 link.textContent = state.isApp ? "Install" : "Download"; 1394 if (!state.isApp) link.setAttribute("download", ""); 1395 link.addEventListener("click", (event) => handleAction(event, href)); 1396 1397 bottom.append(meta, link); 1398 body.append(heading, desc, bottom); 1399 card.append(preview, body); 1400 return card; 1401 } 1402 1403 function renderPlugins() { 1404 const filtered = getFilteredPlugins(); 1405 els.plugins.className = "plugins" + (state.view === "list" ? " list" : ""); 1406 els.plugins.replaceChildren(...filtered.map(makeCard)); 1407 els.empty.classList.toggle("visible", filtered.length === 0); 1408 els.plugins.style.display = filtered.length === 0 ? "none" : ""; 1409 requestAnimationFrame(() => { 1410 const content = document.querySelector(".content"); 1411 const canScroll = content.scrollHeight > content.clientHeight + 1; 1412 els.footer.classList.toggle("after-scroll", canScroll); 1413 }); 1414 1415 const currentCategory = CATEGORIES.find((item) => item.key === state.category); 1416 els.currentTitle.textContent = state.app !== "all" 1417 ? getAppLabel(state.app) 1418 : (currentCategory ? currentCategory.label : "All plugins"); 1419 els.resultLabel.textContent = filtered.length === PLUGINS.length 1420 ? PLUGINS.length + " plugins available" 1421 : filtered.length + " of " + PLUGINS.length + " shown"; 1422 } 1423 1424 function render() { 1425 els.gridView.classList.toggle("active", state.view === "grid"); 1426 els.listView.classList.toggle("active", state.view === "list"); 1427 els.footer.hidden = state.isApp; 1428 els.brand.hidden = state.isApp; 1429 renderFilters(); 1430 renderPlugins(); 1431 } 1432 1433 els.gridView.addEventListener("click", () => { 1434 state.view = "grid"; 1435 render(); 1436 }); 1437 1438 els.listView.addEventListener("click", () => { 1439 state.view = "list"; 1440 render(); 1441 }); 1442 1443 els.search.addEventListener("input", (event) => { 1444 state.search = event.target.value; 1445 renderPlugins(); 1446 }); 1447 1448 els.reset.addEventListener("click", () => { 1449 state.category = "all"; 1450 state.app = "all"; 1451 state.search = ""; 1452 els.search.value = ""; 1453 render(); 1454 }); 1455
1456 async function init() { 1457 renderStaticIcons(); 1458 try { 1459 loadPlugins(); 1460 } catch (error) { 1461 console.warn(error); 1462 els.currentTitle.textContent = "Plugins unavailable"; 1463 els.resultLabel.textContent = "Could not load plugin data"; 1464 els.empty.classList.add("visible"); 1465 els.empty.querySelector("h3").textContent = "Plugins unavailable"; 1466 els.empty.querySelector("p").textContent = "Run package.py and reload the page."; 1467 els.reset.hidden = true; 1468 els.footer.hidden = true; 1469 return; 1470 } 1471 render(); 1472 } 1473 1474 init(); 1475 </script>
1475 1476</body> 1477</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.