Snippets Collections
<a href="https://maticz.com/enterprise-blockchain-development”>Enterprise Blockchain Development </a>
Binance Exchange Clone script is a pre-fabricated software package that permits entrepreneurs to embark on their own crypto exchange platform like Binance. Like any other business, the revenue streams of Binance clone rely on various aspects, including the business model, target audience, and services they offer. 

Trading Fees

Users pay a charge to the platform for every trade they make. The fee varies depending on the exchange platform, and it can be a fixed amount or percentage of trading volume. 

Listing Fees

The Fee can vary depending on the crypto exchange platform and the popularity of the project. These fees generated from the binance clone can be the source of revenue for the platform, especially if the platform gains popularity among crypto projects. 

Withdrawal Fees

Withdrawal fees are charged to users when they withdraw their cryptocurrencies from the platform. The fee can vary depending on the cryptocurrency and the platform. 

Margin trading fees

Margin trading is a feature that allows users to trade with borrowed funds. The platform charges a fee for providing the margin trading feature. 

Security token offerings (STOs)

STOs are a type of fundraising method where investors buy security tokens in exchange for funds. The platform charges a fee for hosting STOs. 

Initial Exchange Offering (IEO)

Initial Exchange Offering (IEO) is a fundraising method where cryptocurrency projects sell their tokens directly on an exchange platform. The platform charges a fee for hosting IEOs. 

Advertising and sponsorships

Cryptocurrency exchange platforms can generate revenue from advertising and sponsorships. Projects in the cryptocurrency industry pay for advertising space on the platform.

If you are planning to launch your own cryptocurrency exchange platform and are looking for a Binance clone script, Maticz Technologies is a leading technology solutions provider offering a ready-made Binance clone script solution.
Expand your business potential with Our AI Development Services
Receive scalable AI software development services with Maticz. Our experts are focused in helping our clients to achieve a transformational output by incorporating the latest technologies like machine learning, large language models, deep learning, and augmented reality.
Harness the potential of our experts to fulfill your AI-related business needs.
{
  "pollId": 166,
  "associationId": 58,
  "domainTypeId": 15,
  "title": "Travel Preferences Surve",
  "description": "Understand the health and wellness habits of participants to develop programs that promote better lifestyle choices.",
  "startDate": "2024-07-22T18:30:00",
  "endDate": "2024-07-28T18:30:00",
 
  "pollQuestions": [
    {
      "pollQuestionId": 210,
      "pollId": 0,
      "pollOrSurveyAnswerTypeId": 104,
      "questionContent": "What type of exercise do you prefer or not? ",
      "answers": [
        {
          "pollAnswerId": 1018,
          "answerContent": "Cardio",
          "noOfVotes": 0
        },
        {
          "pollAnswerId": 1019,
          "answerContent": "Strength training",
          "noOfVotes": 0
        },
        {
          "pollAnswerId": 1020,
          "answerContent": "Yoga/Pilates",
          "noOfVotes": 0
        }
      ],
      "answerObj": null
    },
    {
      "pollQuestionId": 211,
      "pollId": 0,
      "pollOrSurveyAnswerTypeId": 104,
      "questionContent": "How many days a week do you engage in physical activity?",
      "answers": [
        {
          "pollAnswerId": 1021,
          "answerContent": "One",
          "noOfVotes": 0
        },
        {
          "pollAnswerId": 1022,
          "answerContent": "Two",
          "noOfVotes": 0
        }
      ],
      "answerObj": null
    }
  ],
  "pollTargetAudience": {
    "pollTargetAudienceId": 139,
    "pollId": 166,
    "pollOrSurveyTargetTypeId": 100,
    "pollTargetId": [
      145,
      140
    ]
  },
  "isPollCreator": true,
  "status": "string",
  "noOfVotes": 0,
  "noOfReports": 0,
  "creatorName": "kiran Reddy",
  "domainTypeName": "Survey"
}
{
  "pollId": 166,
  "associationId": 58,
  "domainTypeId": 15,
  "title": "Travel Preferences Surve",
  "description": "Understand the health and wellness habits of participants to develop programs that promote better lifestyle choices.",
  "startDate": "2024-07-22T18:30:00",
  "endDate": "2024-07-28T18:30:00",
 
  "pollQuestions": [
    {
      "pollQuestionId": 210,
      "pollId": 0,
      "pollOrSurveyAnswerTypeId": 104,
      "questionContent": "What type of exercise do you prefer or not? ",
      "answers": [
        {
          "pollAnswerId": 1018,
          "answerContent": "Cardio",
          "noOfVotes": 0
        },
        {
          "pollAnswerId": 1019,
          "answerContent": "Strength training",
          "noOfVotes": 0
        },
        {
          "pollAnswerId": 1020,
          "answerContent": "Yoga/Pilates",
          "noOfVotes": 0
        }
      ],
      "answerObj": null
    },
    {
      "pollQuestionId": 211,
      "pollId": 0,
      "pollOrSurveyAnswerTypeId": 104,
      "questionContent": "How many days a week do you engage in physical activity?",
      "answers": [
        {
          "pollAnswerId": 1021,
          "answerContent": "One",
          "noOfVotes": 0
        },
        {
          "pollAnswerId": 1022,
          "answerContent": "Two",
          "noOfVotes": 0
        }
      ],
      "answerObj": null
    }
  ],
  "pollTargetAudience": {
    "pollTargetAudienceId": 139,
    "pollId": 166,
    "pollOrSurveyTargetTypeId": 100,
    "pollTargetId": [
      145,
      140
    ]
  },
  "isPollCreator": true,
  "status": "string",
  "noOfVotes": 0,
  "noOfReports": 0,
  "creatorName": "kiran Reddy",
  "domainTypeName": "Survey"
}
#include <stdio.h>

void interchange(int a[], int i, int j) {
    
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}

int partition(int a[], int m, int p) {
    int v = a[m];
    int i = m;
    int j = p;

    do {
        while (a[i] <= v && i < j) {
            i++;
        }

        while (a[j] > v && j > i) {
            j--;
        }

        if (i < j) {
            interchange(a, i, j);
        }
    } while (i < j);

    a[m] = a[j];
    a[j] = v;
    return j;
}


void quick_sort(int a[], int p, int q) {
 
    if (p < q) {
      
        int j = partition(a, p, q);

   
        quick_sort(a, p, j - 1);
        quick_sort(a, j + 1, q);
    }
}

int main() {
    int a[] = {3, 6, 8, 10, 1, 2, 1};
    int n = sizeof(a) / sizeof(a[0]);

    quick_sort(a, 0, n - 1);

 
    for (int i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}
PUT event_heatmap/_settings
{
  "index":{
    "max_result_window": 100000
  }
}
--------------------
const lufthanza = {
  airline: "Lufthanza",
  iataCode: "LH",
  bookings: [],
  book: function (flightNumber, name) {
    this.bookings.push({ flightCode: flightNumber, passenger: name });
    return `${name} booked a flight with this ${this.iataCode} on
	${this.airline} with this ${flightNumber}`;
  },
};

console.log(lufthanza);
console.log(lufthanza.book("KIG808", "David"));


//second object without the function BUT it has the same keys
const etihad = {
  airline: "Etihad",
  iataCode: "EH",
  bookings: [],
};

// create the variable for the book function
const bookingCalc = lufthanza.book;

// create the call on the object that needs that function
bookingCalc.call(etihad, "HLSMSJ", "John");



// using call() to spread into the bookings array from the existing call
const passengerInfo = ['gktu78', 'Kevin']

bookingCalc.call(etihad, ...passengerInfo);

console.log(etihad)
 # dd if=spi.installer.img of=/dev/XXX bs=1M oflag=direct,sync status=progress
<?php get_header(); ?>
 
         
          <div class="page-title page-title-default title-size-large title-design-centered color-scheme-light" style="">
                    <div class="container">
                <h1 class="entry-title title"><?php the_title(); ?>    </h1>
                     <div class="breadcrumbs"><a href="<?php echo get_home_url(); ?>" rel="v:url" property="v:title">Home</a> » <span class="current">Services</span></div><!-- .breadcrumbs -->                                                                        </div>
                </div>
 
 
    <div class="container">
        <div class="row single_serviceSection">
            <div class="col-lg-6">
                <div class="singleServiceContent">
                    <h3>
                        <?php the_title(); ?>
                    </h3>
                    <p>
                        <?php the_content(); ?>
                    </p>
                </div>
            </div>
            <div class="col-lg-6">
                <div class="singleServiceThumbnail">
                    <?php the_post_thumbnail("full"); ?>
                </div>
            </div>
        </div>
        <?php// comments_template(); ?>
    </div>
 
 
 
<?php 
 
get_footer();
 
?>


////////STYLING CSS///////

.single-services .main-page-wrapper > .container {
    max-width: 100%;
}

.single-services .page-title-default {
    width: 100%;
}
.single_serviceSection {
    display: flex;
    flex-direction: row-reverse;
    padding: 100px 0;
} 
<!DOCTYPE html>
<html>
​
<body>
  
<script>
class Car {
  constructor(name) {
    this.brand = name;
  }
​
  present() {
    return 'I have a ' + this.brand;
  }
}
​
class Model extends Car {
  constructor(name, mod) {
    super(name);
    this.model = mod;
  }  
  show() {
    return this.present() + ', it is a ' + this.model
  }
}
​
const mycar = new Model("Ford", "Mustang");
document.write(mycar.show());
</script>
​
</body>
</html>
​
<!DOCTYPE html>
<html>
​
<body>
  
<script>
class Car {
  constructor(name) {
    this.brand = name;
  }
}
​
const mycar = new Car("Ford");
​
document.write(mycar.brand);
</script>
​
</body>
</html>
​
new Card(cardContainer, {
    id: 'instructions',
    icon: 'fa-solid fa-medal',
    title: 'Contests',
    description: 'Where the magic happens! Manage contests and their teams.',
}).click(async () => {
    const modal = await new Modal(null, { id: 'instructions' }).loadContent('index-instructions');
    modal.addButton({
        text: 'OK, got it!',
        close: true,
    })
});
ol.elementor-toc__list-wrapper .elementor-toc__list-item-text-wrapper:before {
    content-visibility: hidden;
}
JavaScript
<script>
document.addEventListener('scroll', function(e) {
var header = document.getElementById('sticky-header');
var scrollTop = window.scrollY || document.documentElement.scrollTop;

if (scrollTop > lastScrollTop) {
// Scroll Down
header.style.transform = 'translateY(-100%)';
} else {
// Scroll Up
header.style.transform = 'translateY(0)';
}
lastScrollTop = scrollTop <= 0 ? 0 : scrollTop; // For Mobile or negative scrolling
}, false);

var lastScrollTop = 0;
</script>

CSS
#sticky-header {
transition: transform 0.3s ease-in-out;
}
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { UserService } from '../Services/userprofile.service';
import { Router } from '@angular/router';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { Member, updateUser } from '../shared/update-user';
import { Subscription, catchError } from 'rxjs';
import { RewardRedeemViewModel, RewardViewModel, UnredeemedRewardModel } from '../shared/reward';
import { RewardService } from '../Services/reward.service';
import { RewardTypeViewModel } from '../shared/reward';

declare var $: any; // Import jQuery

@Component({
  selector: 'app-profile-page',
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule],
  templateUrl: './profile-page.component.html',
  styleUrls: ['./profile-page.component.css']
})
export class ProfilePageComponent implements OnInit, OnDestroy {
  profileForm: FormGroup;
  user: updateUser | undefined;
  member!: Member;
  isEditMode = false;
  errorMessage = '';
  userProfileImage: string | ArrayBuffer = ''; // Add this property to store the Base64 image data
  unredeemedRewards: UnredeemedRewardModel[] = [];
  selectedReward: UnredeemedRewardModel | null = null;

  private userSubscription: Subscription | undefined;
  private redeemSubscription: Subscription | undefined;
  

  constructor(
    private userService: UserService,
    private rewardService: RewardService,
    private router: Router,
    private fb: FormBuilder
  ) {
    this.profileForm = this.fb.group({
      email: ['', [Validators.required, Validators.email]],
      name: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(20)]],
      surname: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(20)]],
      phoneNumber: ['', [Validators.required, Validators.maxLength(10)]],
      physical_Address: ['', [Validators.required, Validators.maxLength(255)]],
      photo: ['']
    });
  }

  ngOnInit(): void {
    const userId = JSON.parse(localStorage.getItem('User') || '').userId;
    console.log('User ID from local storage:', userId);
    
    this.userSubscription = this.userService.getUserById(userId).pipe(
      catchError(error => {
        console.error('Error fetching user profile:', error);
        // Handle error
        return []; // Return empty array or default value as per your logic
      })
    ).subscribe({
      next: (result) => {
        console.log('User data received:', result);
        this.user = result;
        this.profileForm.patchValue(this.user);
        
        // Assign userProfileImage
        this.userProfileImage = `data:image/jpeg;base64,${this.user.Photo}`; // Ensure this.user.Photo contains the Base64 data
        
        // Log userProfileImage and user for debugging
        console.log('User Profile Image:', this.userProfileImage);
        console.log('User:', this.user);

        // Check if the user is a member and fetch member details
      if (this.user.User_Type_ID !== 3) {
        this.userService.getMemberByUserId(userId).subscribe(
          memberResult => {
            this.member = memberResult;
            console.log('Member data received:', this.member);
            this.loadUnredeemedRewards(); // Load rewards if the user is a member
          },
          memberError => {
            console.error('Error fetching member data:', memberError);
          }
        );
      }
      },
      complete: () => {
        console.log('getUserById subscription completed');
      }
    });
  
    this.isEditMode = false;
    this.loadUnredeemedRewards();
  }

  ngOnDestroy(): void {
    // Clean up subscriptions
    if (this.userSubscription) {
      this.userSubscription.unsubscribe();
    }
    if (this.redeemSubscription) {
      this.redeemSubscription.unsubscribe();
    }
  }

  clearForm() {
    this.profileForm.reset();
  }

  enableEditMode(event: Event) {
    event.preventDefault();
    this.isEditMode = true;
    this.profileForm.enable();
  }

  openSaveModal() {
    if (this.profileForm.invalid) {
      this.showValidationErrors();
      $('#errorModal').modal('show');
      return;
    }
    $('#saveConfirmationModal').modal('show');
  }

  showValidationErrors() {
    const invalidFields: string[] = [];
    Object.keys(this.profileForm.controls).forEach(key => {
      const controlErrors = this.profileForm.get(key)?.errors;
      if (controlErrors) {
        Object.keys(controlErrors).forEach(errorKey => {
          invalidFields.push(`${key}: ${errorKey}`);
        });
      }
    });
    this.errorMessage = `Please enter a valid input: ${invalidFields.join(', ')}`;
  }

  dismissModal() {
    $('#saveConfirmationModal').modal('hide');
  }

  dismissErrorModal() {
    $('#errorModal').modal('hide');
  }

  confirmSave() {
    this.dismissModal();
    this.onSubmit();
    this.isEditMode = false; // Disable edit mode after confirmation
  }

  onSubmit() {
    if (this.profileForm.valid) {
      const userId = JSON.parse(localStorage.getItem('User')!).userId;
      this.userService.updateUser(userId,this.profileForm.value).subscribe({
        next: (result) => {
          console.log('User to be updated:', result);
          this.router.navigateByUrl(`/ProfilePage/${userId}`);
          alert('Successfully updated profile');
        },
        error: () => {
          console.error('Error updating user profile:');
          alert('Error updating profile');
        }
      });
    }
  }

  onPhotoChange(event: Event): void {
    if (!this.isEditMode) return;

    const input = event.target as HTMLInputElement;
    if (input.files && input.files[0]) {
      const reader = new FileReader();
      reader.onload = (e: any) => {
        this.userProfileImage = e.target.result; // Update the image source
        this.profileForm.patchValue({ photo: e.target.result }); // Update the form control
      };
      reader.readAsDataURL(input.files[0]);
    }
  }

  goBack() {
    const userTypeId = JSON.parse(localStorage.getItem('User')!).userTypeId;
    const userId = JSON.parse(localStorage.getItem('User')!).userId;
    if (userTypeId === 1) {  // Ensure userTypeID is compared as string
      this.router.navigateByUrl(`/OwnerHome/${userId}`);
    } else if (userTypeId === 2) {
      this.router.navigateByUrl(`/EmployeeHome/${userId}`);
    } else if (userTypeId === 3) {
      this.router.navigateByUrl(`/Home/${userId}`);
    }
  }

  changePassword() {
    this.router.navigateByUrl('/ChangePasswordPage');
  }


  // Method to load rewards for the current user
  loadUnredeemedRewards(): void {
    const memberId = this.member.Member_ID;
    this.rewardService.getUnredeemedRewardsForMember(memberId).subscribe(
      rewards => {
        this.unredeemedRewards = rewards;
        console.log('Unredeemed Rewards:', this.unredeemedRewards);
      },
      error => {
        console.error('Error fetching unredeemed rewards:', error);
      }
    );
  }

  // Method to open redeem modal for a reward
  openRedeemModal(reward: UnredeemedRewardModel): void {
    this.selectedReward = reward;
    $('#redeemRewardModal').modal('show');
  }

  // Method to dismiss redeem modal
  dismissRedeemModal(): void {
    $('#redeemRewardModal').modal('hide');
  }

  // Method to confirm redeeming a reward
  confirmRedeem(): void {
    if (!this.selectedReward) {
      return;
    }
    const redeemRequest = new RewardRedeemViewModel();
    redeemRequest.MemberId = this.member?.Member_ID ?? 0;
    redeemRequest.RewardId = this.selectedReward.reward_ID;

    // Call backend service to redeem the reward
    this.redeemSubscription = this.rewardService.redeemReward(redeemRequest).subscribe({
      next: () => {
        // Show success modal on successful redemption
        $('#successModal').modal('show');
        // Remove redeemed reward from the list
        this.unredeemedRewards = this.unredeemedRewards.filter(r => r.reward_ID !== this.selectedReward?.reward_ID);
      },
      error: (error) => {
        console.error('Error redeeming reward:', error);
        // Handle error
      }
    });
    this.dismissRedeemModal();
  }

  // Method to dismiss success modal
  dismissSuccessModal(): void {
    $('#successModal').modal('hide');
  }
}
<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/bundled/lenis.js"></script>

<script>
const lenis = new Lenis({
  duration: 1.2,
  easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // https://www.desmos.com/calculator/brs54l4xou
  direction: 'vertical', // vertical, horizontal
  gestureDirection: 'vertical', // vertical, horizontal, both
  smooth: true,
  mouseMultiplier: 1,
  smoothTouch: false,
  touchMultiplier: 2,
  infinite: false,
})

//get scroll value
lenis.on('scroll', ({ scroll, limit, velocity, direction, progress }) => {
  console.log({ scroll, limit, velocity, direction, progress })
})

function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}

requestAnimationFrame(raf)
</script>
const allValid = [...this.template.querySelectorAll('lightning-input')].reduce((validSoFar, inputField) => {
            inputField.reportValidity();
            return validSoFar && inputField.checkValidity();
        }, true);

        if (allValid) {
            console.log('All fields are valid');
        } else {
            console.log('Please complete all required fields.');
        }
selector {
overflow-x: auto; /* Enables horizontal scrolling if content overflows */
-webkit-overflow-scrolling: touch; /* Smooth scrolling for touch devices */
}
const playBoard = document.querySelector(".play-board");

const scoreElement = document.querySelector(".score");

const highScoreElement = document.querySelector(".high-score");

const controls = document.querySelectorAll(".controls i");

​

let gameOver = false;

let foodX, foodY;

let snakeX = 5, snakeY = 5;

let velocityX = 0, velocityY = 0;

let snakeBody = [];

let setIntervalId;

let score = 0;

​

// Getting high score from the local storage

let highScore = localStorage.getItem("high-score") || 0;

highScoreElement.innerText = `High Score: ${highScore}`;

​

const updateFoodPosition = () => {

    // Passing a random 1 -  value as food position

    foodX = Math.floor(Math.random() * 30) + 1;

    foodY = Math.floor(Math.random() * 30) + 1;

}

​

const handleGameOver = () => {

    // Clearing the timer and reloading the page on game over

    clearInterval(setIntervalId);

    alert("Game Over! Press OK to replay...");

    location.reload();

}
30
​

const changeDirection = e => {

    // Changing velocity value based on key press

    if(e.key === "ArrowUp" && velocityY != 1) {

        velocityX = 0;

        velocityY = -1;

    } else if(e.key === "ArrowDown" && velocityY != -1) {

        velocityX = 0;

        velocityY = 1;

    } else if(e.key === "ArrowLeft" && velocityX != 1) {

        velocityX = -1;

        velocityY = 0;

    } else if(e.key === "ArrowRight" && velocityX != -1) {

        velocityX = 1;

        velocityY = 0;

    }
// Online C compiler to run C program online
#include <stdio.h>

int main() {
    int limit,i,j,tmp;
    int a[1000];
    printf("enter the size of an array\n");
    scanf("%d",&limit);
    printf("enter the value of array\n");
    for(i=0;i<limit;i++){
        scanf("%d",&a[i]);
    }
    for(i=0;i<limit-1;i++){
        for(j=i+1;j<limit;j++){
            if(a[i]>a[j]){
                tmp=a[i];
                a[i]=a[j];
                a[j]=tmp;
            }
        }
    }
    printf("sorted array\n");
    for(i=0;i<limit;i++){
        printf("%d,\t",a[i]);
    }
    
    
    
    return 0;
}
function clearContent() {
  var app = SpreadsheetApp;
  var clearContent = app.getActiveSpreadsheet().getActiveSheet();
  //clearContent.getRange("A1:F11").clear();
  clearContent.getRange("A1:F11").clearFormat();
}
function SetOtherSheets() {
  var app = SpreadsheetApp;
  var SetOtherSheets = app.getActiveSpreadsheet().getActiveSheet();
  
  // เลือกชีทตามชื่อ
  var targetSheet = app.getActiveSpreadsheet().getSheetByName('Sheet20');
  //targetSheet.getRange(1,1).setValue(7);
  var tempNumber = targetSheet.getRange(1,1).getValue();
  // นำค่าไปเขียนไว้ที่ชีทอื่น
  var secondSheet = app.getActiveSpreadsheet().getSheetByName('Sheet19');
  secondSheet.getRange(10,1).setValue(tempNumber);
}
// Enable WP_DEBUG mode
define( 'WP_DEBUG', true );

// Enable Debug logging to the /wp-content/debug.log file
define( 'WP_DEBUG_LOG', true );

// Disable display of errors and warnings
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

// Use dev versions of core JS and CSS files (only needed if you are modifying these core files)
define( 'SCRIPT_DEBUG', true );
String mdtType = 'GenAiPromptTemplate';
String endpoint = URL.getOrgMyDomainUrl().toExternalForm() + '/services/Soap/m/61.0';

// Setup SOAP body
String reqBody ='<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mdt="http://soap.sforce.com/2006/04/metadata"><soapenv:Header><mdt:SessionHeader><mdt:sessionId>' + UserInfo.getSessionId() + '</mdt:sessionId></mdt:SessionHeader><mdt:CallOptions><mdt:client></mdt:client><mdt:defaultNamespace></mdt:defaultNamespace></mdt:CallOptions><mdt:AllOrNoneHeader><mdt:allOrNone>true</mdt:allOrNone></mdt:AllOrNoneHeader></soapenv:Header><soapenv:Body><mdt:listMetadata><queries><folder></folder><type>'+mdtType+'</type></queries></mdt:listMetadata></soapenv:Body></soapenv:Envelope>';

// Setup POST request
HttpRequest req = new HttpRequest();
req.setEndpoint(endpoint);
req.setMethod('POST');
req.setHeader('Content-Type', 'text/xml; charset=UTF-8');
req.setHeader('SOAPAction', 'listMetadata');
req.setBody(reqBody);

// Output the list
System.debug(JSON.serializePretty(getMetadataTypeFullNameListMapFromListResponseBody(new Http().send(req).getBody())));


/**
 * Method to get a list of metadata per metadata type
 */
public Map<String,String[]> getMetadataTypeFullNameListMapFromListResponseBody(String listResponseBody){ 

	// XML Namespaces
	final String evNs = 'http://schemas.xmlsoap.org/soap/envelope/';
	final String mdNs = 'http://soap.sforce.com/2006/04/metadata';

	// Create output
	Map<String,String[]> mdtTypeNameFullNameListMap = new Map<String,String[]>();

	// Read XML
	Dom.Document domDocument = new Dom.Document();
	domDocument.load(listResponseBody);	

	// Parse XML into list, read the <Body> --> than <listMetadataResponse> to get the list of <results>
	Dom.XmlNode[] resultElements = domDocument.getRootElement()?.getChildElement('Body',evNs)?.getChildElement('listMetadataResponse',mdNs)?.getChildElements();

	// Iterate all result elements. Each result element represents a single metadata item from the list
	for(Dom.XmlNode resultElement : resultElements){

		// Variables for fetching the metadata type and metadata fullname
		String mdtType;
		String fullName;

		// Get all metadata type specific attributes
		for(Dom.XmlNode grandChildElement : resultElement.getChildElements()){
			if(mdtType == null && grandChildElement.getName() == 'type'){
				mdtType  = grandChildElement.getText();
			}else if (fullName == null && grandChildElement.getName() == 'fullName'){
				fullName  = grandChildElement.getText();
			}
		}

		if(!mdtTypeNameFullNameListMap.containsKey(mdtType)){
			mdtTypeNameFullNameListMap.put(mdtType, new String[]{});
		}
		mdtTypeNameFullNameListMap.get(mdtType).add(fullName);
	}
	return mdtTypeNameFullNameListMap;
}
function Looping() {
  var app = SpreadsheetApp;
  var loopActiveSheet = app.getActiveSpreadsheet().getActiveSheet();
  //var someCell = loopActiveSheet.getRange(8,1).getValue();
  //someCell = someCell+5;
  //loopActiveSheet.getRange(9,1).setValue(someCell+5);
  //Logger.log(someCell);
  //------------
  for (var i=8;i<12;i++){
  var someCell = loopActiveSheet.getRange(i,1).getValue();
  someCell = someCell+5;
  loopActiveSheet.getRange(i,2).setValue(someCell+5);
  //-----------
  //Logger.log('hello');
  //Logger.log(i);
  }
}
function learnBasic() {

  var app = SpreadsheetApp;
  var ss = app.getActiveSpreadsheet();
  var ActiveSheet = ss.getActiveSheet();

  var temp1text = ActiveSheet.getRange(4, 1).getValue();
  ActiveSheet.getRange(6,2).setValue(temp1text);
}
#!/bin/bash

# Create directories
mkdir -p your-bot/commands/admin
mkdir -p your-bot/commands/general
mkdir -p your-bot/commands/match
mkdir -p your-bot/commands/warning

# Create data.json file
cat <<EOL > your-bot/data.json
{
  "matches": {},
  "matchCounter": 1,
  "playersELO": {},
  "playerWarnings": {},
  "karma": {},
  "playerStats": {}
}
EOL

# Create .env file
cat <<EOL > your-bot/.env
DISCORD_TOKEN=your-token-here
DISCORD_PREFIX=!
QUEUE_CHANNEL_ID=your-queue-channel-id
MATCH_CATEGORY_ID=your-match-category-id
MATCH_LOG_CHANNEL_ID=your-match-log-channel-id
EOL

# Create package.json file
cat <<EOL > your-bot/package.json
{
  "name": "your-bot",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "discord.js": "^14.0.0",
    "dotenv": "^16.0.0"
  },
  "type": "module"
}
EOL

# Create index.js file
cat <<EOL > your-bot/index.js
import { Client, GatewayIntentBits, Partials, PermissionsBitField, ChannelType, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import dotenv from 'dotenv';
import { loadCommands } from './loadCommands.js';
import { registerCommands } from './registerCommands.js';

dotenv.config();

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const dataFilePath = path.join(__dirname, 'data.json');

console.log(\`Data file path: \${dataFilePath}\`);

let data;
let matches = {};
let matchCounter = 1;
let playersELO = {};
let playerWarnings = {};
let playerStats = {};
let karma = {};
let queue = [];

const maps = ['BW', 'SB', 'PORT', 'COMP', 'ANK', 'MEX', 'EE'];

const saveMatchData = () => {
  const dataToSave = { matches, matchCounter, playersELO, playerWarnings, karma, playerStats };
  fs.writeFileSync(dataFilePath, JSON.stringify(dataToSave, null, 2), 'utf-8');
};

const loadMatchData = () => {
  try {
    const fileContents = fs.readFileSync(dataFilePath, 'utf8');
    const data = JSON.parse(fileContents);
    matches = data.matches || {};
    matchCounter = data.matchCounter || 1;
    playersELO = data.playersELO || {};
    playerWarnings = data.playerWarnings || {};
    karma = data.karma || {};
    playerStats = data.playerStats || {};
  } catch (error) {
    console.error(\`Error reading file at path: \${dataFilePath}\`);
    console.error(error);
  }
};

loadMatchData();

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
    GatewayIntentBits.GuildMembers,
    GatewayIntentBits.GuildVoiceStates,
    GatewayIntentBits.GuildPresences,
    GatewayIntentBits.GuildMessageReactions
  ],
  partials: [Partials.Channel, Partials.Message, Partials.Reaction]
});

client.once('ready', async () => {
  console.log(\`Bot is ready! Logged in as \${client.user.tag}\`);
  await setupQueueMessage();
  registerCommands(client);
});

client.on('messageCreate', async (message) => {
  if (!message.content.startsWith(process.env.DISCORD_PREFIX) || message.author.bot) return;
  const args = message.content.slice(process.env.DISCORD_PREFIX.length).trim().split(/ +/);
  const command = args.shift().toLowerCase();

  try {
    await loadCommands(command, message, args);
  } catch (error) {
    console.error(\`Error executing command \${command}:\`, error);
    message.reply('There was an error executing that command.');
  }
});

client.on('interactionCreate', async interaction => {
  try {
    if (interaction.isButton()) {
      await handleButtonInteraction(interaction);
    } else if (interaction.isCommand()) {
      const command = interaction.commandName;
      switch (command) {
        case 'setupreaction':
          await setupQueueMessage(interaction);
          break;
        case 'eloreset':
          await eloresetCommand(interaction);
          break;
        case 'warningreset':
          await warningresetCommand(interaction);
          break;
        case 'leaderboard':
          await leaderboardCommand(interaction);
          break;
        default:
          await interaction.reply({ content: 'Unknown command interaction.', ephemeral: true });
          break;
      }
    }
  } catch (error) {
    console.error('Error handling interaction:', error);
    if (interaction.isCommand() || interaction.isButton()) {
      await interaction.reply({ content: 'There was an error handling this interaction.', ephemeral: true });
    }
  }
});

const setupQueueMessage = async () => {
  try {
    const channel = await client.channels.fetch(process.env.QUEUE_CHANNEL_ID);
    const embed = new EmbedBuilder()
      .setColor('#00ff26')
      .setTitle('🎮 CSL West Competitive Queue 🎮')
      .setDescription('Use the buttons below to join or leave the queue.\n\n**Current Queue:**\nNo one in the queue (0/10)')
      .setFooter({ text: 'Powered by Maverick', iconURL: 'https://i.imgur.com/wTF3RuJ.png' });

    const row = new ActionRowBuilder()
      .addComponents(
        new ButtonBuilder()
          .setCustomId('join_queue')
          .setLabel('Join Queue')
          .setStyle(ButtonStyle.Success)
          .setEmoji('✅'),
        new ButtonBuilder()
          .setCustomId('leave_queue')
          .setLabel('Leave Queue')
          .setStyle(ButtonStyle.Danger)
          .setEmoji('❌')
      );

    await channel.send({ embeds: [embed], components: [row] });
  } catch (error) {
    console.error('Error setting up queue message:', error);
  }
};

const joinQueue = async (interaction) => {
  try {
    await interaction.deferReply({ ephemeral: true });

    const user = interaction.user;
    const member = await interaction.guild.members.fetch(user.id);
    if (!queue.includes(user.id) && member.roles.cache.some(role => ['Pug Approved', 'Admin', 'Score Reporter'].includes(role.name))) {
      queue.push(user.id);
      await updateQueueMessage();
      if (queue.length === 10) {
        await createMatch(interaction.guild);
      }
      await interaction.editReply({ content: 'You have joined the queue!' });
    } else {
      await interaction.editReply({ content: 'You are already in the queue or do not have permission to join the queue.' });
    }
  } catch (error) {
    console.error('Error joining queue:', error);
    if (!interaction.replied) {
      await interaction.editReply({ content: 'There was an error joining the queue.' });
    }
  }
};

const leaveQueue = async (interaction) => {
  try {
    await interaction.deferReply({ ephemeral: true });

    const user = interaction.user;
    const index = queue.indexOf(user.id);
    if (index > -1) {
      queue.splice(index, 1);
      await updateQueueMessage();
      await interaction.editReply({ content: 'You have left the queue!' });
    } else {
      await interaction.editReply({ content: 'You are not in the queue!' });
    }
  } catch (error) {
    console.error('Error leaving queue:', error);
    if (!interaction.replied) {
      await interaction.editReply({ content: 'There was an error leaving the queue.' });
    }
  }
};

const updateQueueMessage = async () => {
  try {
    const channel = await client.channels.fetch(process.env.QUEUE_CHANNEL_ID);
    const messages = await channel.messages.fetch({ limit: 10 });
    const queueMessage = messages.find(msg => msg.embeds[0]?.title === '🎮 CSL West Competitive Queue 🎮');

    if (queueMessage) {
      const description = queue.length > 0 
        ? `${queue.map(id => \`<@${id}>\`).join('\n')}\n\n**(${queue.length}/10)**`
        : 'No one in the queue (0/10)';

      const embed = new EmbedBuilder()
        .setColor('#00ff26')
        .setTitle('🎮 CSL West Competitive Queue 🎮')
        .setDescription(\`Use the buttons below to join or leave the queue.\n\n**Current Queue:**\n\${description}\`)
        .setFooter({ text: 'Powered by Maverick', iconURL: 'https://i.imgur.com/wTF3RuJ.png' });

      const row = new ActionRowBuilder()
        .addComponents(
          new ButtonBuilder()
            .setCustomId('join_queue')
            .setLabel('Join Queue')
            .setStyle(ButtonStyle.Success)
            .setEmoji('✅'),
          new ButtonBuilder()
            .setCustomId('leave_queue')
            .setLabel('Leave Queue')
            .setStyle(ButtonStyle.Danger)
            .setEmoji('❌')
        );

      await queueMessage.edit({ embeds: [embed], components: [row] });
    }
  } catch (error) {
    console.error('Error updating queue message:', error);
  }
};

const createMatch = async (guild) => {
  try {
    const matchCategory = guild.channels.cache.get(process.env.MATCH_CATEGORY_ID);
    const team1Voice = await guild.channels.create({
      name: \`Match \${matchCounter} - Team 1\`,
      type: ChannelType.GuildVoice,
      parent: matchCategory,
      userLimit: 6,
      permissionOverwrites: [
        {
          id: guild.roles.everyone.id,
          allow: [PermissionsBitField.Flags.Connect],
        },
      ],
    });
    const team2Voice = await guild.channels.create({
      name: \`Match \${matchCounter} - Team 2\`,
      type: ChannelType.GuildVoice,
      parent: matchCategory,
      userLimit: 6,
      permissionOverwrites: [
        {
          id: guild.roles.everyone.id,
          allow: [PermissionsBitField.Flags.Connect],
        },
      ],
    });
    const matchText = await guild.channels.create({
      name: \`match-\${matchCounter}\`,
      type: ChannelType.GuildText,
      parent: matchCategory,
      permissionOverwrites: [
        {
          id: guild.roles.everyone.id,
          allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages],
        },
      ],
    });

    const team1Captain = queue.shift();
    const team2Captain = queue.shift();
    const remainingPlayers = queue.splice(0, 8);
    const randomMap = maps[Math.floor(Math.random() * maps.length)];
    matches[matchCounter] = {
      team1: [team1Captain],
      team2: [team2Captain],
      remaining: remainingPlayers,
      pickingOrder: ['team1', 'team2', 'team2', 'team1', 'team1', 'team2', 'team1'],
      currentPick: 0,
      mapVotes: {},
      chosenMap: randomMap,
      textChannelId: matchText.id
    };

    saveMatchData();

    console.log(\`Match \${matchCounter} created with map \${randomMap}\`);

    await updateQueueMessage();
    await updateMatchMessage(matchCounter);

    setTimeout(async () => {
      if (!matches[matchCounter]) return;
      const mostVotedMap = Object.entries(matches[matchCounter].mapVotes)
        .reduce((max, entry) => entry[1] > max[1] ? entry : max, ['', 0])[0];
      if (mostVotedMap) {
        matches[matchCounter].chosenMap = mostVotedMap;
      }
      await updateMatchMessage(matchCounter);
    }, 3 * 60 * 1000);

    matchCounter++;
  } catch (error) {
    console.error('Error creating match:', error);
  }
};

const updateMatchMessage = async (matchNumber) => {
  try {
    const match = matches[matchNumber];
    const matchText = client.channels.cache.get(match.textChannelId);
    if (!matchText) return;

    const team1 = match.team1.map(id => \`<@${id}>\`).join('\n') || 'No players yet';
    const team2 = match.team2.map(id => \`<@${id}>\`).join('\n') || 'No players yet';
    const embed = new EmbedBuilder()
      .setTitle(\`🎮 Match \${matchNumber} 🎮\`)
      .setColor('#ff4500')
      .setDescription('**Match Details**')
      .addFields(
        { name: '🏆 Team 1 Captain', value: \`<@${match.team1[0]}>\`, inline: true },
        { name: '🏆 Team 2 Captain', value: \`<@${match.team2[0]}>\`, inline: true },
        { name: '\u200B', value: '\u200B', inline: true },
        { name: '👥 Team 1', value: team1, inline: true },
        { name: '👥 Team 2', value: team2, inline: true },
        { name: '🗺️ Map', value: \`**${match.chosenMap}**\`, inline: true }
      )
      .setThumbnail('https://i.imgur.com/xfe96CL.png')
      .setImage('https://i.imgur.com/jyuglDa.png')
      .setFooter({ text: 'Powered by Maverick', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    const playerPickRows = [];
    for (let i = 0; i < match.remaining.length; i += 5) {
      const row = new ActionRowBuilder()
        .addComponents(
          await Promise.all(
            match.remaining.slice(i, i + 5).map(async playerId => {
              const member = await client.guilds.cache.get(matchText.guild.id).members.fetch(playerId);
              const nickname = member.nickname || member.user.username;
              return new ButtonBuilder()
                .setCustomId(\`pick_\${matchNumber}_\${playerId}\`)
                .setLabel(\`Pick \${nickname}\`)
                .setStyle(ButtonStyle.Primary);
            })
          )
        );
      playerPickRows.push(row);
    }

    const mapVoteRows = [];
    for (let i = 0; i < maps.length; i += 5) {
      const row = new ActionRowBuilder()
        .addComponents(
          maps.slice(i, i + 5).map(map => new ButtonBuilder()
            .setCustomId(\`map_vote_\${matchNumber}_\${map}\`)
            .setLabel(\`\${map} (\${match.mapVotes[map] || 0})\`)
            .setStyle(ButtonStyle.Secondary)
          )
        );
      mapVoteRows.push(row);
    }

    const messages = await matchText.messages.fetch({ limit: 10 });
    const matchMessage = messages.find(msg => msg.embeds[0]?.title === \`🎮 Match \${matchNumber} 🎮\`);
    if (matchMessage) {
      try {
        await matchMessage.delete();
      } catch (error) {
        console.error(\`Failed to delete message: \${error.message}\`);
      }
    }
    await matchText.send({ embeds: [embed], components: [...playerPickRows, ...mapVoteRows] });
  } catch (error) {
    console.error('Error updating match message:', error);
  }
};

const handleButtonInteraction = async (interaction) => {
  try {
    const customId = interaction.customId;

    if (customId.startsWith('map_vote_')) {
      await voteMap(interaction);
    } else if (customId.startsWith('join_queue')) {
      await joinQueue(interaction);
    } else if (customId.startsWith('leave_queue')) {
      await leaveQueue(interaction);
    } else if (customId.startsWith('pick_')) {
      await handlePick(interaction);
    } else {
      await interaction.reply({ content: 'Unknown button interaction.', ephemeral: true });
    }
  } catch (error) {
    console.error('Error handling button interaction:', error);
    await interaction.reply({ content: 'There was an error handling this button interaction.', ephemeral: true });
  }
};

const handlePick = async (interaction) => {
  try {
    const [_, matchNumber, playerId] = interaction.customId.split('_');
    const match = matches[matchNumber];

    if (!match) {
      await interaction.reply({ content: \`Match \${matchNumber} not found.\`, ephemeral: true });
      return;
    }

    const user = interaction.user;
    const currentPickTeam = match.pickingOrder[match.currentPick];
    const isCaptain = (user.id === match.team1[0] && currentPickTeam === 'team1') || 
                      (user.id === match.team2[0] && currentPickTeam === 'team2');

    if (!isCaptain) {
      await interaction.reply({ content: 'Only the respective captain can pick for their team on their turn.', ephemeral: true });
      return;
    }

    if (!match.remaining.includes(playerId)) {
      await interaction.reply({ content: 'Invalid player ID for picking.', ephemeral: true });
      return;
    }

    const team = match.pickingOrder[match.currentPick];
    match[team].push(playerId);
    match.remaining = match.remaining.filter(id => id !== playerId);
    match.currentPick++;

    if (match.currentPick === match.pickingOrder.length && match.remaining.length === 1) {
      match.team2.push(match.remaining[0]);
      match.remaining = [];
    }

    await updateMatchMessage(matchNumber);
    await interaction.reply({ content: \`Player <@${playerId}> has been picked for \${team === 'team1' ? 'Team 1' : 'Team 2'}.\`, ephemeral: true });
  } catch (error) {
    console.error('Error handling pick:', error);
    await interaction.reply({ content: 'There was an error handling the pick.', ephemeral: true });
  }
};

const voteMap = async (interaction) => {
  try {
    const [_, matchNumber, map] = interaction.customId.split('_');
    const userId = interaction.user.id;

    if (!matchNumber || isNaN(matchNumber) || matchNumber < 1) {
      console.error(\`Invalid matchNumber: \${matchNumber}\`);
      await interaction.reply({ content: 'Invalid match number.', ephemeral: true });
      return;
    }

    const match = matches[matchNumber];
    if (!match) {
      console.error(\`Match \${matchNumber} not found.\`);
      await interaction.reply({ content: \`Match \${matchNumber} not found.\`, ephemeral: true });
      return;
    }

    if (!match.mapVotes) match.mapVotes = {};

    if (match.mapVotes[map] && match.mapVotes[map].includes(userId)) {
      await interaction.reply({ content: 'You have already voted for this map.', ephemeral: true });
      return;
    }

    for (const m in match.mapVotes) {
      match.mapVotes[m] = match.mapVotes[m].filter(id => id !== userId);
    }

    if (!match.mapVotes[map]) match.mapVotes[map] = [];
    match.mapVotes[map].push(userId);

    const mostVotedMap = Object.entries(match.mapVotes).reduce((max, entry) => entry[1].length > max[1].length ? entry : max, ['', []])[0];
    match.chosenMap = mostVotedMap;

    await interaction.reply({ content: \`Your vote for \${map} has been recorded!\`, ephemeral: true });
    await updateMatchMessage(matchNumber);
  } catch (error) {
    console.error('Error voting map:', error);
    await interaction.reply({ content: 'There was an error voting for the map.', ephemeral: true });
  }
};

const findUserMatch = (userId) => {
  for (const [id, match] of Object.entries(matches)) {
    if (match.team1.includes(userId) || match.team2.includes(userId) || match.remaining.includes(userId)) {
      return id;
    }
  }
  return null;
};

client.login(process.env.DISCORD_TOKEN);
EOL

# Create command files

# Admin Commands
cat <<EOL > your-bot/commands/admin/clearQueue.js
export const clearQueueCommand = async (message) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    queue = [];
    await updateQueueMessage();
    message.reply('The queue has been cleared.');
  } catch (error) {
    console.error('Error clearing queue:', error);
    message.reply('There was an error clearing the queue.');
  }
};
EOL

cat <<EOL > your-bot/commands/admin/giveElo.js
export const giveEloCommand = async (message, args) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    const userId = args[0].replace('<@', '').replace('>', '');
    const eloChange = parseInt(args[1], 10);

    if (!playersELO[userId]) playersELO[userId] = 0;
    playersELO[userId] += eloChange;

    saveData();
    message.reply(\`ELO for <@${userId}> has been changed by \${eloChange}. New ELO: \${playersELO[userId]}\`);
  } catch (error) {
    console.error('Error giving ELO:', error);
    message.reply('There was an error changing the ELO.');
  }
};
EOL

cat <<EOL > your-bot/commands/admin/resetElo.js
export const resetEloCommand = async (message) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    playersELO = {};
    saveData();
    message.reply('All ELO has been reset.');
  } catch (error) {
    console.error('Error resetting ELO:', error);
    message.reply('There was an error resetting the ELO.');
  }
};
EOL

cat <<EOL > your-bot/commands/admin/resetWarnings.js
export const warningResetCommand = async (message) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    playerWarnings = {};
    saveData();
    message.reply('All warnings have been reset.');
  } catch (error) {
    console.error('Error resetting warnings:', error);
    message.reply('There was an error resetting the warnings.');
  }
};
EOL

# General Commands
cat <<EOL > your-bot/commands/general/profile.js
export const profileCommand = async (message, args) => {
  const userId = args[0] ? args[0].replace('<@', '').replace('>', '') : message.author.id;
  const user = await message.guild.members.fetch(userId);
  const username = user.nickname || user.user.username;
  const elo = playersELO[userId] || 0;
  const userKarma = karma[userId] || 0;
  const stats = playerStats[userId] || {};

  const defaultMapStats = { wins: 0, losses: 0 };
  const maps = {
    BW: stats.BW || defaultMapStats,
    PORT: stats.PORT || defaultMapStats,
    ANK: stats.ANK || defaultMapStats,
    COMP: stats.COMP || defaultMapStats,
    SB: stats.SB || defaultMapStats,
    MEX: stats.MEX || defaultMapStats,
    EE: stats.EE || defaultMapStats
  };

  const totalWins = Object.values(maps).reduce((acc, map) => acc + map.wins, 0);
  const totalLosses = Object.values(maps).reduce((acc, map) => acc + map.losses, 0);

  const embed = new EmbedBuilder()
    .setTitle(\`\${username}'s Profile\`)
    .setThumbnail(user.user.displayAvatarURL({ dynamic: true }))
    .addFields(
      { name: 'ELO', value: elo.toString(), inline: true },
      { name: 'Karma', value: userKarma.toString(), inline: true },
      { name: '\u200B', value: '\u200B', inline: true }
    )
    .addFields(
      { name: 'Map Stats:', value: '\u200B' },
      { name: 'Black Widow', value: \`\${maps.BW.wins} wins \${maps.BW.losses} losses\`, inline: true },
      { name: 'Port', value: \`\${maps.PORT.wins} wins \${maps.PORT.losses} losses\`, inline: true },
      { name: 'Ankara', value: \`\${maps.ANK.wins} wins \${maps.ANK.losses} losses\`, inline: true },
      { name: 'Compound', value: \`\${maps.COMP.wins} wins \${maps.COMP.losses} losses\`, inline: true },
      { name: 'Sub Base', value: \`\${maps.SB.wins} wins \${maps.SB.losses} losses\`, inline: true },
      { name: 'Mexico', value: \`\${maps.MEX.wins} wins \${maps.MEX.losses} losses\`, inline: true },
      { name: 'Eagle Eye', value: \`\${maps.EE.wins} wins \${maps.EE.losses} losses\`, inline: true },
      { name: 'Total Wins', value: totalWins.toString(), inline: true },
      { name: 'Total Losses', value: totalLosses.toString(), inline: true }
    )
    .setColor('#ff4500')
    .setFooter({ text: 'FPS Game Stats', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
    .setTimestamp();

  message.reply({ embeds: [embed] });
};
EOL

cat <<EOL > your-bot/commands/general/leaderboard.js
export const leaderboardCommand = async (message) => {
  try {
    const sortedPlayers = Object.entries(playersELO).sort((a, b) => b[1] - a[1]).slice(0, 25);
    const leaderboard = await Promise.all(
      sortedPlayers.map(async ([userId, elo], index) => {
        const user = await message.guild.members.fetch(userId).catch(() => null);
        return \`#\${index + 1}  |  \${elo}  |  \${user ? \`<@${user.id}>\` : \`Unknown User\`}\`;
      })
    );

    if (leaderboard.length === 0) {
      leaderboard.push('No players available');
    }

    const embed = new EmbedBuilder()
      .setColor('#00ff26')
      .setTitle('Top 25 Pug Players')
      .addFields({ name: 'Rank | Elo | Player', value: leaderboard.join('\n') })
      .setFooter({ text: 'Use .lb or .leaderboard to see the leaderboard at any time', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    message.reply({ embeds: [embed] });
  } catch (error) {
    console.error('Error fetching leaderboard:', error);
    message.reply('There was an error fetching the leaderboard.');
  }
};
EOL

cat <<EOL > your-bot/commands/general/elo.js
export const eloCommand = async (message, args) => {
  try {
    const userId = args[0] ? args[0].replace('<@', '').replace('>', '') : message.author.id;
    const elo = playersELO[userId] || 0;
    message.reply(\`<@${userId}> has \${elo} ELO.\`);
  } catch (error) {
    console.error('Error fetching ELO:', error);
    message.reply('There was an error fetching the ELO.');
  }
};
EOL

# Match Commands
cat <<EOL > your-bot/commands/match/cancelMatch.js
export const cancelMatchCommand = async (message, args) => {
  const roleIds = ['1075756565023445022', '1258877265870192673']; // Array of role IDs
  const hasAdminPermission = message.member.permissions.has(PermissionsBitField.Flags.Administrator);
  const hasRequiredRole = roleIds.some(roleId => message.member.roles.cache.has(roleId));

  const hasPermission = hasAdminPermission || hasRequiredRole; // Check for permissions

  let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

  if (!matchId && hasPermission) {
    matchId = args[0];
  }

  if (!matchId || !matches[matchId]) {
    try {
      await message.reply('Invalid match ID or no active match found.');
    } catch (error) {
      console.error('Error sending reply:', error);
    }
    return;
  }

  if (!hasPermission) { // Check if user has the necessary permissions
    try {
      await message.reply('You do not have permission to cancel matches.');
    } catch (error) {
      console.error('Error sending reply:', error);
    }
    return;
  }

  try {
    const match = matches[matchId];
    delete matches[matchId];
    saveMatchData();

    const guild = message.guild;
    const matchCategory = await guild.channels.fetch(process.env.MATCH_CATEGORY_ID);

    // Fetch channels from cache or fetch from API if not cached
    const team1Voice = guild.channels.cache.get(match.team1VoiceChannelId) || await guild.channels.fetch(match.team1VoiceChannelId);
    const team2Voice = guild.channels.cache.get(match.team2VoiceChannelId) || await guild.channels.fetch(match.team2VoiceChannelId);
    const matchText = guild.channels.cache.get(match.textChannelId) || await guild.channels.fetch(match.textChannelId);

    if (team1Voice) await team1Voice.delete();
    if (team2Voice) await team2Voice.delete();
    if (matchText) await matchText.delete();

    await message.reply(\`Match \${matchId} has been canceled.\`);
  } catch (error) {
    console.error('Error canceling match:', error);
    try {
      await message.reply('There was an error canceling the match.');
    } catch (replyError) {
      console.error('Error sending error reply:', replyError);
    }
  }
};
EOL

cat <<EOL > your-bot/commands/match/needSub.js
export const needSubCommand = async (message, args) => {
  const roles = ['1255072045574652035', '1075756565023445022', '1258877265870192673'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
      !roles.some(role => message.member.roles.cache.has(role))) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    if (!args[0] || !args[0].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention a valid user to sub.');
    }

    const userId = message.author.id;
    const playerId = args[0].replace('<@', '').replace('>', '');
    const matchId = findUserMatch(userId);

    if (!matchId) {
      return message.reply('You are not part of any active matches.');
    }

    const match = matches[matchId];
    const team = match.team1.includes(playerId) ? 'team1' : 'team2';
    const playerIndex = match[team].indexOf(playerId);

    if (playerIndex === -1) {
      return message.reply('Player not found in any team.');
    }

    const subMessage = await message.channel.send(\`<@${playerId}> has requested a substitution. React with ❌ within 2 minutes if you are still here.\`);
    await subMessage.react('❌');

    const filter = (reaction, user) => reaction.emoji.name === '❌' && user.id === playerId;
    const collector = subMessage.createReactionCollector({ filter, time: 120000 });

    collector.on('collect', () => {
      subMessage.edit(\`<@${playerId}> is still active.\`);
      collector.stop();
    });

    collector.on('end', async collected => {
      if (collected.size === 0) {
        const newPlayerId = queue.shift();
        if (!newPlayerId) {
          return message.channel.send('No available substitutes in the queue.');
        }

        match[team][playerIndex] = newPlayerId;
        await updateMatchMessage(matchId);

        message.channel.send(\`<@${playerId}> has been substituted by <@${newPlayerId}> in \${team === 'team1' ? 'Team 1' : 'Team 2'}.\`);
      }
    });
  } catch (error) {
    console.error('Error handling substitution:', error);
    message.reply('There was an error handling the substitution.');
  }
};
EOL

cat <<EOL > your-bot/commands/match/pick.js
export const pickCommand = async (message, args) => {
  try {
    if (!args[0] || !args[0].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention a valid user to pick.');
    }

    const playerId = args[0].replace('<@', '').replace('>', '');
    const userId = message.author.id;
    const matchId = findUserMatch(userId);

    if (!matchId) {
      return message.reply('You are not part of any active matches.');
    }

    const match = matches[matchId];
    const currentPickIndex = match.team1.length + match.team2.length - 2;

    if (currentPickIndex >= match.pickingOrder.length) {
      return message.reply('All picks have already been made.');
    }

    const pickingTeam = match.pickingOrder[currentPickIndex] === 'team1' ? 'team1' : 'team2';

    if (!match.remaining.includes(playerId)) {
      return message.reply('Invalid player ID for picking.');
    }

    match[pickingTeam].push(playerId);
    match.remaining = match.remaining.filter(id => id !== playerId);

    await updateMatchMessage(matchId);

    message.reply(\`Player <@${playerId}> picked for \${pickingTeam === 'team1' ? 'Team 1' : 'Team 2'}.\`);
  } catch (error) {
    console.error('Error picking player:', error);
    message.reply('There was an error picking the player.');
  }
};
EOL

cat <<EOL > your-bot/commands/match/pt.js
export const ptCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022', '1258877265870192673'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1]) &&
    !message.member.roles.cache.has(roles[2])) {
    return message.reply('You do not have permission to use this command.');
  }
  try {
    if (args.length < 1) {
      return message.reply('Please specify the team number (1, 2, or 0) and an optional message.');
    }

    const userId = message.author.id;
    const teamNumber = parseInt(args[0]);

    if (isNaN(teamNumber) || (teamNumber < 0 || teamNumber > 2)) {
      return message.reply('Invalid team number. Use 1 for Team 1, 2 for Team 2, or 0 for both teams.');
    }

    const additionalMessage = args.slice(1).join(' ');

    let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

    if (!matchId) {
      return message.reply('You are not part of any active matches.');
    }

    const match = matches[matchId];
    let teamMentions = '';

    if (teamNumber === 0) {
      const allTeams = [...match.team1, ...match.team2];
      teamMentions = allTeams.map(id => \`<@${id}>\`).join(' ');
    } else if (teamNumber === 1) {
      teamMentions = match.team1.map(id => \`<@${id}>\`).join(' ');
    } else if (teamNumber === 2) {
      teamMentions = match.team2.map(id => \`<@${id}>\`).join(' ');
    }

    const finalMessage = \`\${teamMentions} \${additionalMessage}\`;

    try {
      const matchCategory = await message.client.channels.fetch(process.env.MATCH_CATEGORY_ID);
      const matchText = matchCategory.children.cache.find(c => c.name === \`match-\${matchId}\`);
      if (!matchText) {
        return message.reply('Match text channel not found.');
      }
      await matchText.send(finalMessage);
      message.reply('Message sent.');
    } catch (error) {
      console.error('Error sending message:', error);
      message.reply('There was an error sending the message. Please try again later.');
    }
  } catch (error) {
    console.error('Error in PT command:', error);
    message.reply('There was an error executing the PT command.');
  }
};
EOL

cat <<EOL > your-bot/commands/match/report.js
export const reportCommand = async (message, args) => {
  const roleIds = ['1075756565023445022', '1258877265870192673']; // Array of role IDs
  const hasAdminPermission = message.member.permissions.has(PermissionsBitField.Flags.Administrator);
  const hasRequiredRole = roleIds.some(roleId => message.member.roles.cache.has(roleId));

  const hasPermission = hasAdminPermission || hasRequiredRole; // Check for permissions

  let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

  if (!matchId && hasPermission) {
    matchId = args[0];
  }

  if (!matchId || !matches[matchId]) {
    return message.reply('Invalid match ID or no active match found.');
  }

  try {
    const winningTeamNumber = hasPermission ? args[1] : args[0];
    const match = matches[matchId];
    const team1 = match.team1;
    const team2 = match.team2;
    let winningTeam, losingTeam;

    if (winningTeamNumber === '1') {
      winningTeam = team1;
      losingTeam = team2;
      updateElo(team1, team2);
      updateStats(team1, team2, match.chosenMap, true);
    } else if (winningTeamNumber === '2') {
      winningTeam = team2;
      losingTeam = team1;
      updateElo(team2, team1);
      updateStats(team2, team1, match.chosenMap, true);
    } else {
      return message.reply('Invalid winning team.');
    }

    await message.reply(\`Match \${matchId} has been reported and the channels will be deleted.\`);

    const guild = message.guild;
    const matchCategory = await guild.channels.fetch(process.env.MATCH_CATEGORY_ID);
    const team1Voice = matchCategory.children.cache.find(c => c.name === \`Match \${matchId} - Team 1\`);
    const team2Voice = matchCategory.children.cache.find(c => c.name === \`Match \${matchId} - Team 2\`);
    const matchText = matchCategory.children.cache.find(c => c.name === \`match-\${matchId}\`);
    if (team1Voice) await team1Voice.delete();
    if (team2Voice) await team2Voice.delete();
    if (matchText) await matchText.delete();

    delete matches[matchId];
    saveMatchData();

    const reporter = message.author;
    logMatch(matchId, winningTeam, losingTeam, \`Team \${winningTeamNumber}\`, reporter);
  } catch (error) {
    console.error('Error reporting match:', error);
    message.reply('There was an error reporting the match.');
  }
};
EOL

cat <<EOL > your-bot/commands/match/replace.js
export const replaceCommand = async (message, args) => {
  const roleIds = ['1075756565023445022', '1258877265870192673']; // Array of role IDs
  const hasAdminPermission = message.member.permissions.has(PermissionsBitField.Flags.Administrator);
  const hasRequiredRole = roleIds.some(roleId => message.member.roles.cache.has(roleId));

  const hasPermission = hasAdminPermission || hasRequiredRole; // Check for permissions

  let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

  if (!matchId && hasPermission) {
    matchId = args[2];
  }

  if (!matchId || !matches[matchId]) {
    return message.reply('Invalid match ID or no active match found.');
  }

  if (!hasPermission) { // Check if user has the necessary permissions
    return message.reply('You do not have permission to replace players.');
  }

  try {
    if (args.length < 2 || !args[0].match(/^<@!?(\d+)>$/) || !args[1].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention the old player and the new player in the correct format.');
    }

    const oldPlayerId = args[0].replace('<@', '').replace('>', '').replace('!', '');
    const newPlayerId = args[1].replace('<@', '').replace('>', '').replace('!', '');
    const match = matches[matchId];
    const team = match.team1.includes(oldPlayerId) ? 'team1' : match.team2.includes(oldPlayerId) ? 'team2' : null;

    if (!team) {
      return message.reply('Old player is not found in any team.');
    }

    const playerIndex = match[team].indexOf(oldPlayerId);

    if (playerIndex === -1) {
      return message.reply('Old player not found in the team.');
    }

    match[team][playerIndex] = newPlayerId;

    await updateMatchMessage(matchId);

    message.reply(\`Player <@${oldPlayerId}> has been replaced by <@${newPlayerId}> in \${team === 'team1' ? 'Team 1' : 'Team 2'}.\`);
  } catch (error) {
    console.error('Error replacing player:', error);
    message.reply('There was an error replacing the player.');
  }
};
EOL

cat <<EOL > your-bot/commands/match/suspendUser.js
export const suspendUserCommand = async (message, args) => {
  try {
    const userId = args[0].replace('<@', '').replace('>', '');
    const duration = parseInt(args[1]);
    const reason = args.slice(2).join(' ');

    if (!karma[userId]) karma[userId] = {};
    karma[userId].suspendedUntil = Date.now() + duration * 60000;
    karma[userId].reason = reason;
    saveData();

    message.reply(\`<@${userId}> has been suspended for \${duration} minutes. Reason: \${reason}\`);
  } catch (error) {
    console.error('Error suspending user:', error);
    message.reply('There was an error suspending the user.');
  }
};
EOL

cat <<EOL > your-bot/commands/match/unSuspendUser.js
export const unSuspendUserCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1])) {
    return message.reply('You do not have permission to use this command.');
  }
  try {
    const userId = args[0].replace('<@', '').replace('>', '');

    if (karma[userId] && karma[userId].suspendedUntil) {
      delete karma[userId].suspendedUntil;
      delete karma[userId].reason;
      saveData();
      message.reply(\`<@${userId}>'s suspension has been lifted.\`);
    } else {
      message.reply(\`<@${userId}> is not currently suspended.\`);
    }
  } catch (error) {
    console.error('Error unsuspending user:', error);
    message.reply('There was an error lifting the suspension.');
  }
};
EOL

# Warning Commands
cat <<EOL > your-bot/commands/warning/warn.js
export const warnCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1])) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    if (!args[0] || !args[0].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention a valid user to warn.');
    }

    const userId = args[0].replace('<@', '').replace('>', '');
    const reason = args.slice(1).join(' ') || 'No reason provided';

    if (!playerWarnings[userId]) {
      playerWarnings[userId] = { count: 0, reasons: [] };
    }

    playerWarnings[userId].count += 1;
    playerWarnings[userId].reasons.push(reason);
    saveData();

    const embed = new EmbedBuilder()
      .setColor('#ff4500')
      .setTitle('User Warned')
      .addFields(
        { name: 'User', value: \`<@${userId}>\`, inline: true },
        { name: 'Warnings', value: playerWarnings[userId].count.toString(), inline: true },
        { name: 'Reason', value: reason, inline: true }
      )
      .setThumbnail('https://i.imgur.com/wTF3RuJ.png')
      .setFooter({ text: 'Stay in line, soldier!', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    message.reply({ embeds: [embed] });
  } catch (error) {
    console.error('Error warning user:', error);
    message.reply('There was an error warning the user.');
  }
};
EOL

cat <<EOL > your-bot/commands/warning/warns.js
export const warnsCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1])) {
    return message.reply('You do not have permission to use this command.');
  }
  try {
    const userId = args[0] ? args[0].replace('<@', '').replace('>', '') : message.author.id;
    const userWarnings = playerWarnings[userId] ? playerWarnings[userId].count : 0;
    const reasons = playerWarnings[userId] ? playerWarnings[userId].reasons : [];
    const username = message.mentions.users.first() ? message.mentions.users.first().username : message.author.username;

    const embed = new EmbedBuilder()
      .setColor('#ff4500')
      .setTitle(\`\${username}'s Warnings\`)
      .addFields(
        { name: 'Warnings', value: userWarnings.toString(), inline: true },
        { name: 'Reasons', value: reasons.length > 0 ? reasons.join('\n') : 'No warnings', inline: true }
      )
      .setThumbnail('https://i.imgur.com/wTF3RuJ.png')
      .setFooter({ text: 'Stay in line, soldier!', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    message.reply({ embeds: [embed] });
  } catch (error) {
    console.error('Error fetching warnings:', error);
    message.reply('There was an error fetching the warnings.');
  }
};
EOL

# Load and register commands
cat <<EOL > your-bot/loadCommands.js
import { clearQueueCommand } from './commands/admin/clearQueue.js';
import { giveEloCommand } from './commands/admin/giveElo.js';
import { resetEloCommand } from './commands/admin/resetElo.js';
import { warningResetCommand } from './commands/admin/resetWarnings.js';
import { profileCommand } from './commands/general/profile.js';
import { leaderboardCommand } from './commands/general/leaderboard.js';
import { eloCommand } from './commands/general/elo.js';
import { cancelMatchCommand } from './commands/match/cancelMatch.js';
import { needSubCommand } from './commands/match/needSub.js';
import { pickCommand } from './commands/match/pick.js';
import { ptCommand } from './commands/match/pt.js';
import { reportCommand } from './commands/match/report.js';
import { replaceCommand } from './commands/match/replace.js';
import { suspendUserCommand } from './commands/match/suspendUser.js';
import { unSuspendUserCommand } from './commands/match/unSuspendUser.js';
import { warnCommand } from './commands/warning/warn.js';
import { warnsCommand } from './commands/warning/warns.js';

const commandMap = {
  'clearqueue': clearQueueCommand,
  'giveelo': giveEloCommand,
  'resetelo': resetEloCommand,
  'resetwarnings': warningResetCommand,
  'profile': profileCommand,
  'leaderboard': leaderboardCommand,
  'elo': eloCommand,
  'cancelmatch': cancelMatchCommand,
  'needsub': needSubCommand,
  'pick': pickCommand,
  'pt': ptCommand,
  'report': reportCommand,
  'replace': replaceCommand,
  'suspenduser': suspendUserCommand,
  'unsuspenduser': unSuspendUserCommand,
  'warn': warnCommand,
  'warns': warnsCommand
};

export const loadCommands = async (command, message, args) => {
  if (commandMap[command]) {
    await commandMap[command](message, args);
  } else {
    message.reply('Unknown command.');
  }
};
EOL

cat <<EOL > your-bot/registerCommands.js
export const registerCommands = (client) => {
  const commands = [
    {
      name: 'setupreaction',
      description: 'Recreates the reaction message to join the queue',
      type: 1,
    },
    {
      name: 'eloreset',
      description: 'Resets all ELO, must be superuser',
      type: 1,
    },
    {
      name: 'warningreset',
      description: 'Resets all warnings, must be admin',
      type: 1,
    },
    {
      name: 'leaderboard',
      description: 'Leaderboard in the stats channel',
      type: 1,
    }
  ];

  const guild = client.guilds.cache.first();
  guild.commands.set(commands).then(() => console.log('Commands registered'));
};
EOL

# Install dependencies
npm install
EOL

echo "Setup completed successfully. You can now navigate to the 'your-bot' directory, add your .env values, and run 'npm start' to start your bot."
sudo add-apt-repository --remove ‘deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ jammy main’
sudo add-apt-repository ‘deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ jammy main’
	time_and_zone = reset_date_time.getSuffix("T");
	reset_date = reset_date_time.getPrefix("T");
// 	info time_and_zone;
	//////// calculating time /////
	if(frequency == "Weekly")
	{
	 	next = reset_date.addDay(7);
	}else if (frequency == "Monthly")
	{
		nex = reset_date.addMonth(1);
	}else if (frequency == "Quarterly") 
    {
		next = reset_date.addMonth(3);
    }
	else if ( frequency == "Yearly" ) 
    {
		next = reset_date.addYear(1);
    }
	
	end_date_time = nex.toString("yyyy-MM-dd")+"T"+time_and_zone;
// iteration_list = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
searchValue = {"contactId":contact_Id, "createdTimeRange":reset_date_time +","+end_date_time }; 
response = zoho.desk.searchRecords(organization_id, "tickets", searchValue, 0, 1000, "zoho_desk");
sudo ln -s /etc/apt/sources.list.d/official-package-repositories.list /etc/apt/sources.list
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all
$localFolderPath = "C:\UWP_1.0.0.0_Test]\*"
$localPackage = "C:\UWP_1.0.0.0_Test\UWP_1.0.0.0_x64.msixbundle"
$certName = Get-ChildItem -Path $localFolderPath -Include *.cer

certutil.exe -addstore TrustedPeople $certName[0].FullName
DISM.EXE /Online /Add-ProvisionedAppxPackage /PackagePath:$localPackage /SkipLicense
const warnCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1])) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    if (!args[0] || !args[0].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention a valid user to warn.');
    }

    const userId = args[0].replace('<@', '').replace('>', '');
    const reason = args.slice(1).join(' ') || 'No reason provided';

    if (!playerWarnings[userId]) {
      playerWarnings[userId] = { count: 0, reasons: [] };
    }

    playerWarnings[userId].count += 1;
    playerWarnings[userId].reasons.push(reason);
    saveData();

    const embed = new EmbedBuilder()
      .setColor('#ff4500')
      .setTitle('User Warned')
      .addFields(
        { name: 'User', value: `<@${userId}>`, inline: true },
        { name: 'Warnings', value: playerWarnings[userId].count.toString(), inline: true },
        { name: 'Reason', value: reason, inline: true }
      )
      .setThumbnail('https://i.imgur.com/wTF3RuJ.png')
      .setFooter({ text: 'Stay in line, soldier!', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    message.reply({ embeds: [embed] });
  } catch (error) {
    console.error('Error warning user:', error);
    message.reply('There was an error warning the user.');
  }
};

const warnsCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1])) {
    return message.reply('You do not have permission to use this command.');
  }
  try {
    const userId = args[0] ? args[0].replace('<@', '').replace('>', '') : message.author.id;
    const userWarnings = playerWarnings[userId] ? playerWarnings[userId].count : 0;
    const reasons = playerWarnings[userId] ? playerWarnings[userId].reasons : [];
    const username = message.mentions.users.first() ? message.mentions.users.first().username : message.author.username;

    const embed = new EmbedBuilder()
      .setColor('#ff4500')
      .setTitle(`${username}'s Warnings`)
      .addFields(
        { name: 'Warnings', value: userWarnings.toString(), inline: true },
        { name: 'Reasons', value: reasons.length > 0 ? reasons.join('\n') : 'No warnings', inline: true }
      )
      .setThumbnail('https://i.imgur.com/wTF3RuJ.png')
      .setFooter({ text: 'Stay in line, soldier!', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    message.reply({ embeds: [embed] });
  } catch (error) {
    console.error('Error fetching warnings:', error);
    message.reply('There was an error fetching the warnings.');
  }
};

const profileCommand = async (message, args) => {
  const userId = args[0] ? args[0].replace('<@', '').replace('>', '') : message.author.id;
  const user = await message.guild.members.fetch(userId);
  const username = user.nickname || user.user.username;
  const elo = playersELO[userId] || 0;
  const userKarma = karma[userId] || 0;
  const stats = playerStats[userId] || {};

  const defaultMapStats = { wins: 0, losses: 0 };
  const maps = {
    BW: stats.BW || defaultMapStats,
    PORT: stats.PORT || defaultMapStats,
    ANK: stats.ANK || defaultMapStats,
    COMP: stats.COMP || defaultMapStats,
    SB: stats.SB || defaultMapStats,
    MEX: stats.MEX || defaultMapStats,
    EE: stats.EE || defaultMapStats
  };

  const totalWins = Object.values(maps).reduce((acc, map) => acc + map.wins, 0);
  const totalLosses = Object.values(maps).reduce((acc, map) => acc + map.losses, 0);

  const embed = new EmbedBuilder()
    .setTitle(`${username}'s Profile`)
    .setThumbnail(user.user.displayAvatarURL({ dynamic: true }))
    .addFields(
      { name: 'ELO', value: elo.toString(), inline: true },
      { name: 'Karma', value: userKarma.toString(), inline: true },
      { name: '\u200B', value: '\u200B', inline: true }
    )
    .addFields(
      { name: 'Map Stats:', value: '\u200B' },
      { name: 'Black Widow', value: `${maps.BW.wins} wins ${maps.BW.losses} losses`, inline: true },
      { name: 'Port', value: `${maps.PORT.wins} wins ${maps.PORT.losses} losses`, inline: true },
      { name: 'Ankara', value: `${maps.ANK.wins} wins ${maps.ANK.losses} losses`, inline: true },
      { name: 'Compound', value: `${maps.COMP.wins} wins ${maps.COMP.losses} losses`, inline: true },
      { name: 'Sub Base', value: `${maps.SB.wins} wins ${maps.SB.losses} losses`, inline: true },
      { name: 'Mexico', value: `${maps.MEX.wins} wins ${maps.MEX.losses} losses`, inline: true },
      { name: 'Eagle Eye', value: `${maps.EE.wins} wins ${maps.EE.losses} losses`, inline: true },
      { name: 'Total Wins', value: totalWins.toString(), inline: true },
      { name: 'Total Losses', value: totalLosses.toString(), inline: true }
    )
    .setColor('#ff4500')
    .setFooter({ text: 'FPS Game Stats', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
    .setTimestamp();

  message.reply({ embeds: [embed] });
};

const leaderboardCommand = async (message) => {
  try {
    const sortedPlayers = Object.entries(playersELO).sort((a, b) => b[1] - a[1]).slice(0, 25);
    const leaderboard = await Promise.all(
      sortedPlayers.map(async ([userId, elo], index) => {
        const user = await message.guild.members.fetch(userId).catch(() => null);
        return `#${index + 1}  |  ${elo}  |  ${user ? `<@${user.id}>` : `Unknown User`}`;
      })
    );

    if (leaderboard.length === 0) {
      leaderboard.push('No players available');
    }

    const embed = new EmbedBuilder()
      .setColor('#00ff26')
      .setTitle('Top 25 Pug Players')
      .addFields({ name: 'Rank | Elo | Player', value: leaderboard.join('\n') })
      .setFooter({ text: 'Use .lb or .leaderboard to see the leaderboard at any time', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    message.reply({ embeds: [embed] });
  } catch (error) {
    console.error('Error fetching leaderboard:', error);
    message.reply('There was an error fetching the leaderboard.');
  }
};

const eloCommand = async (message, args) => {
  try {
    const userId = args[0] ? args[0].replace('<@', '').replace('>', '') : message.author.id;
    const elo = playersELO[userId] || 0;
    message.reply(`<@${userId}> has ${elo} ELO.`);
  } catch (error) {
    console.error('Error fetching ELO:', error);
    message.reply('There was an error fetching the ELO.');
  }
};

const pickCommand = async (message, args) => {
  try {
    if (!args[0] || !args[0].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention a valid user to pick.');
    }

    const playerId = args[0].replace('<@', '').replace('>', '');
    const userId = message.author.id;
    const matchId = findUserMatch(userId);

    if (!matchId) {
      return message.reply('You are not part of any active matches.');
    }

    const match = matches[matchId];
    const currentPickIndex = match.team1.length + match.team2.length - 2;

    if (currentPickIndex >= match.pickingOrder.length) {
      return message.reply('All picks have already been made.');
    }

    const pickingTeam = match.pickingOrder[currentPickIndex] === 'team1' ? 'team1' : 'team2';

    if (!match.remaining.includes(playerId)) {
      return message.reply('Invalid player ID for picking.');
    }

    match[pickingTeam].push(playerId);
    match.remaining = match.remaining.filter(id => id !== playerId);

    await updateMatchMessage(matchId);

    message.reply(`Player <@${playerId}> picked for ${pickingTeam === 'team1' ? 'Team 1' : 'Team 2'}.`);
  } catch (error) {
    console.error('Error picking player:', error);
    message.reply('There was an error picking the player.');
  }
};

const needSubCommand = async (message, args) => {
  const roles = ['1255072045574652035', '1075756565023445022', '1258877265870192673'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
      !roles.some(role => message.member.roles.cache.has(role))) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    if (!args[0] || !args[0].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention a valid user to sub.');
    }

    const userId = message.author.id;
    const playerId = args[0].replace('<@', '').replace('>', '');
    const matchId = findUserMatch(userId);

    if (!matchId) {
      return message.reply('You are not part of any active matches.');
    }

    const match = matches[matchId];
    const team = match.team1.includes(playerId) ? 'team1' : 'team2';
    const playerIndex = match[team].indexOf(playerId);

    if (playerIndex === -1) {
      return message.reply('Player not found in any team.');
    }

    const subMessage = await message.channel.send(`<@${playerId}> has requested a substitution. React with ❌ within 2 minutes if you are still here.`);
    await subMessage.react('❌');

    const filter = (reaction, user) => reaction.emoji.name === '❌' && user.id === playerId;
    const collector = subMessage.createReactionCollector({ filter, time: 120000 });

    collector.on('collect', () => {
      subMessage.edit(`<@${playerId}> is still active.`);
      collector.stop();
    });

    collector.on('end', async collected => {
      if (collected.size === 0) {
        const newPlayerId = queue.shift();
        if (!newPlayerId) {
          return message.channel.send('No available substitutes in the queue.');
        }

        match[team][playerIndex] = newPlayerId;
        await updateMatchMessage(matchId);

        message.channel.send(`<@${playerId}> has been substituted by <@${newPlayerId}> in ${team === 'team1' ? 'Team 1' : 'Team 2'}.`);
      }
    });
  } catch (error) {
    console.error('Error handling substitution:', error);
    message.reply('There was an error handling the substitution.');
  }
};

const replaceCommand = async (message, args) => {
  const roleIds = ['1075756565023445022', '1258877265870192673']; // Array of role IDs
  const hasAdminPermission = message.member.permissions.has(PermissionsBitField.Flags.Administrator);
  const hasRequiredRole = roleIds.some(roleId => message.member.roles.cache.has(roleId));

  const hasPermission = hasAdminPermission || hasRequiredRole; // Check for permissions

  let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

  if (!matchId && hasPermission) {
    matchId = args[2];
  }

  if (!matchId || !matches[matchId]) {
    return message.reply('Invalid match ID or no active match found.');
  }

  if (!hasPermission) { // Check if user has the necessary permissions
    return message.reply('You do not have permission to replace players.');
  }

  try {
    if (args.length < 2 || !args[0].match(/^<@!?(\d+)>$/) || !args[1].match(/^<@!?(\d+)>$/)) {
      return message.reply('Please mention the old player and the new player in the correct format.');
    }

    const oldPlayerId = args[0].replace('<@', '').replace('>', '').replace('!', '');
    const newPlayerId = args[1].replace('<@', '').replace('>', '').replace('!', '');
    const match = matches[matchId];
    const team = match.team1.includes(oldPlayerId) ? 'team1' : match.team2.includes(oldPlayerId) ? 'team2' : null;

    if (!team) {
      return message.reply('Old player is not found in any team.');
    }

    const playerIndex = match[team].indexOf(oldPlayerId);

    if (playerIndex === -1) {
      return message.reply('Old player not found in the team.');
    }

    match[team][playerIndex] = newPlayerId;

    await updateMatchMessage(matchId);

    message.reply(`Player <@${oldPlayerId}> has been replaced by <@${newPlayerId}> in ${team === 'team1' ? 'Team 1' : 'Team 2'}.`);
  } catch (error) {
    console.error('Error replacing player:', error);
    message.reply('There was an error replacing the player.');
  }
};

const ptCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022', '1258877265870192673'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1]) &&
    !message.member.roles.cache.has(roles[2])) {
    return message.reply('You do not have permission to use this command.');
  }
  try {
    if (args.length < 1) {
      return message.reply('Please specify the team number (1, 2, or 0) and an optional message.');
    }

    const userId = message.author.id;
    const teamNumber = parseInt(args[0]);

    if (isNaN(teamNumber) || (teamNumber < 0 || teamNumber > 2)) {
      return message.reply('Invalid team number. Use 1 for Team 1, 2 for Team 2, or 0 for both teams.');
    }

    const additionalMessage = args.slice(1).join(' ');

    let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

    if (!matchId) {
      return message.reply('You are not part of any active matches.');
    }

    const match = matches[matchId];
    let teamMentions = '';

    if (teamNumber === 0) {
      const allTeams = [...match.team1, ...match.team2];
      teamMentions = allTeams.map(id => `<@${id}>`).join(' ');
    } else if (teamNumber === 1) {
      teamMentions = match.team1.map(id => `<@${id}>`).join(' ');
    } else if (teamNumber === 2) {
      teamMentions = match.team2.map(id => `<@${id}>`).join(' ');
    }

    const finalMessage = `${teamMentions} ${additionalMessage}`;

    try {
      const matchCategory = await message.client.channels.fetch(process.env.MATCH_CATEGORY_ID);
      const matchText = matchCategory.children.cache.find(c => c.name === `match-${matchId}`);
      if (!matchText) {
        return message.reply('Match text channel not found.');
      }
      await matchText.send(finalMessage);
      message.reply('Message sent.');
    } catch (error) {
      console.error('Error sending message:', error);
      message.reply('There was an error sending the message. Please try again later.');
    }
  } catch (error) {
    console.error('Error in PT command:', error);
    message.reply('There was an error executing the PT command.');
  }
};

const cancelMatchCommand = async (message, args) => {
  const roleIds = ['1075756565023445022', '1258877265870192673']; // Array of role IDs
  const hasAdminPermission = message.member.permissions.has(PermissionsBitField.Flags.Administrator);
  const hasRequiredRole = roleIds.some(roleId => message.member.roles.cache.has(roleId));

  const hasPermission = hasAdminPermission || hasRequiredRole; // Check for permissions

  let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

  if (!matchId && hasPermission) {
    matchId = args[0];
  }

  if (!matchId || !matches[matchId]) {
    try {
      await message.reply('Invalid match ID or no active match found.');
    } catch (error) {
      console.error('Error sending reply:', error);
    }
    return;
  }

  if (!hasPermission) { // Check if user has the necessary permissions
    try {
      await message.reply('You do not have permission to cancel matches.');
    } catch (error) {
      console.error('Error sending reply:', error);
    }
    return;
  }

  try {
    const match = matches[matchId];
    delete matches[matchId];
    saveMatchData();

    const guild = message.guild;
    const matchCategory = await guild.channels.fetch(process.env.MATCH_CATEGORY_ID);

    // Fetch channels from cache or fetch from API if not cached
    const team1Voice = guild.channels.cache.get(match.team1VoiceChannelId) || await guild.channels.fetch(match.team1VoiceChannelId);
    const team2Voice = guild.channels.cache.get(match.team2VoiceChannelId) || await guild.channels.fetch(match.team2VoiceChannelId);
    const matchText = guild.channels.cache.get(match.textChannelId) || await guild.channels.fetch(match.textChannelId);

    if (team1Voice) await team1Voice.delete();
    if (team2Voice) await team2Voice.delete();
    if (matchText) await matchText.delete();

    await message.reply(`Match ${matchId} has been canceled.`);
  } catch (error) {
    console.error('Error canceling match:', error);
    try {
      await message.reply('There was an error canceling the match.');
    } catch (replyError) {
      console.error('Error sending error reply:', replyError);
    }
  }
};


const suspendUserCommand = async (message, args) => {
  try {
    const userId = args[0].replace('<@', '').replace('>', '');
    const duration = parseInt(args[1]);
    const reason = args.slice(2).join(' ');

    if (!karma[userId]) karma[userId] = {};
    karma[userId].suspendedUntil = Date.now() + duration * 60000;
    karma[userId].reason = reason;
    saveData();

    message.reply(`<@${userId}> has been suspended for ${duration} minutes. Reason: ${reason}`);
  } catch (error) {
    console.error('Error suspending user:', error);
    message.reply('There was an error suspending the user.');
  }
};

const unSuspendUserCommand = async (message, args) => {
  const roles = [PermissionsBitField.Flags.Administrator, '1075756565023445022'];
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator) &&
    !message.member.roles.cache.has(roles[1])) {
    return message.reply('You do not have permission to use this command.');
  }
  try {
    const userId = args[0].replace('<@', '').replace('>', '');

    if (karma[userId] && karma[userId].suspendedUntil) {
      delete karma[userId].suspendedUntil;
      delete karma[userId].reason;
      saveData();
      message.reply(`<@${userId}>'s suspension has been lifted.`);
    } else {
      message.reply(`<@${userId}> is not currently suspended.`);
    }
  } catch (error) {
    console.error('Error unsuspending user:', error);
    message.reply('There was an error lifting the suspension.');
  }
};

const saveData = () => {
  const data = { playersELO, playerWarnings, karma, playerStats };
  fs.writeFileSync(dataFilePath, JSON.stringify(data, null, 2), 'utf-8');
};

const logMatch = (matchId, winningTeam, losingTeam, result, reporter) => {
  const logChannel = client.channels.cache.get(process.env.MATCH_LOG_CHANNEL_ID);

  if (!logChannel) {
    console.error('Match log channel not found');
    return;
  }

  const embed = new EmbedBuilder()
    .setTitle(`Match #${matchId} Log`)
    .setColor('#ff4500') // Orange-red color suitable for a competitive FPS theme
    .addFields(
      { name: 'Winners | Team 1', value: winningTeam.map(id => `<@${id}>`).join(' '), inline: true },
      { name: 'Losers | Team 2', value: losingTeam.map(id => `<@${id}>`).join(' '), inline: true },
      { name: 'Reported by', value: `${reporter.username}#${reporter.discriminator} (${reporter.id})` }
    )
    .setFooter({ text: 'Powered by Maverick', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
    .setTimestamp();

  logChannel.send({ embeds: [embed] });
};

const updateElo = (winningTeam, losingTeam) => {
  winningTeam.forEach(player => {
    if (!playersELO[player]) playersELO[player] = 50;
    playersELO[player] += 6;
  });

  losingTeam.forEach(player => {
    if (!playersELO[player]) playersELO[player] = 50;
    playersELO[player] -= 5;
  });

  saveData();
};

const registerCommands = () => {
  const commands = [
    {
      name: 'setupreaction',
      description: 'Recreates the reaction message to join the queue',
      type: 1,
    },
    {
      name: 'eloreset',
      description: 'Resets all ELO, must be superuser',
      type: 1,
    },
    {
      name: 'warningreset',
      description: 'Resets all warnings, must be admin',
      type: 1,
    },
    {
      name: 'leaderboard',
      description: 'Leaderboard in the stats channel',
      type: 1,
    }
  ];

  const guild = client.guilds.cache.first();
  guild.commands.set(commands).then(() => console.log('Commands registered'));
};

client.login(process.env.DISCORD_TOKEN);
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
import {
  Client,
  GatewayIntentBits,
  Partials,
  PermissionsBitField,
  ChannelType,
  EmbedBuilder,
  ActionRowBuilder,
  ButtonBuilder,
  ButtonStyle
} from 'discord.js';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import dotenv from 'dotenv';

dotenv.config();

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const prefix = process.env.DISCORD_PREFIX || '!';
const dataFilePath = path.join(__dirname, 'data.json');

console.log(`Data file path: ${dataFilePath}`);

let data;
let matches = {};
let matchCounter = 1;
let playersELO = {};
let playerWarnings = {};
let playerStats = {};
let karma = {};
let queue = [];

const maps = ['BW', 'SB', 'PORT', 'COMP', 'ANK', 'MEX', 'EE'];

const saveMatchData = () => {
  const dataToSave = { matches, matchCounter, playersELO, playerWarnings, karma, playerStats };
  fs.writeFileSync(dataFilePath, JSON.stringify(dataToSave, null, 2), 'utf-8');
};

const loadMatchData = () => {
  try {
    const fileContents = fs.readFileSync(dataFilePath, 'utf8');
    const data = JSON.parse(fileContents);
    matches = data.matches || {};
    matchCounter = data.matchCounter || 1;
    playersELO = data.playersELO || {};
    playerWarnings = data.playerWarnings || {};
    karma = data.karma || {};
    playerStats = data.playerStats || {};
  } catch (error) {
    console.error(`Error reading file at path: ${dataFilePath}`);
    console.error(error);
  }
};

// Call loadMatchData at the start to initialize
loadMatchData();

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
    GatewayIntentBits.GuildMembers,
    GatewayIntentBits.GuildVoiceStates,
    GatewayIntentBits.GuildPresences,
    GatewayIntentBits.GuildMessageReactions
  ],
  partials: [Partials.Channel, Partials.Message, Partials.Reaction]
});

client.once('ready', async () => {
  console.log(`Bot is ready! Logged in as ${client.user.tag}`);
  await setupQueueMessage();
});

client.on('messageCreate', async (message) => {
  if (!message.content.startsWith(prefix) || message.author.bot) return;
  const args = message.content.slice(prefix.length).trim().split(/ +/);
  const command = args.shift().toLowerCase();

  try {
    switch (command) {
      case 'report': await reportCommand(message, args); break;
      case 'clearqueue': await clearQueueCommand(message); break;
      case 'resetelo': await resetEloCommand(message); break;
      case 'giveelo': await giveEloCommand(message, args); break;
      case 'setmatchlogchannel': await setMatchLogChannelCommand(message, args); break;
      case 'profile': await profileCommand(message, args); break;
      case 'lb': case 'leaderboard': await leaderboardCommand(message); break;
      case 'elo': await eloCommand(message, args); break;
      case 'pick': await pickCommand(message, args); break;
      case 'needsub': await needSubCommand(message, args); break;
      case 'replace': await replaceCommand(message, args); break;
      case 'pt': await ptCommand(message, args); break;
      case 'cooldown': await suspendUserCommand(message, args); break;
      case 'removecd': await unSuspendUserCommand(message, args); break;
      case 'cancel': await cancelMatchCommand(message, args); break;
      case 'warn': await warnCommand(message, args); break;
      case 'warns': await warnsCommand(message, args); break;
      case 'warningsreset': await warningResetCommand(message); break;
    }
  } catch (error) {
    console.error(`Error executing command ${command}:`, error);
    message.reply('There was an error executing that command.');
  }
});

client.on('interactionCreate', async interaction => {
  try {
    if (interaction.isButton()) {
      await handleButtonInteraction(interaction);
    } else if (interaction.isCommand()) {
      const command = interaction.commandName;
      switch (command) {
        case 'setupreaction':
          await setupQueueMessage(interaction);
          break;
        case 'eloreset':
          await eloresetCommand(interaction);
          break;
        case 'warningreset':
          await warningresetCommand(interaction);
          break;
        case 'leaderboard':
          await leaderboardCommand(interaction);
          break;
        default:
          await interaction.reply({ content: 'Unknown command interaction.', ephemeral: true });
          break;
      }
    }
  } catch (error) {
    console.error('Error handling interaction:', error);
    if (interaction.isCommand() || interaction.isButton()) {
      await interaction.reply({ content: 'There was an error handling this interaction.', ephemeral: true });
    }
  }
});

const setupQueueMessage = async () => {
  try {
    const channel = await client.channels.fetch(process.env.QUEUE_CHANNEL_ID);
    const embed = new EmbedBuilder()
      .setColor('#00ff26')
      .setTitle('🎮 CSL West Competitive Queue 🎮')
      .setDescription('Use the buttons below to join or leave the queue.\n\n**Current Queue:**\nNo one in the queue (0/10)')
      .setFooter({ text: 'Powered by Maverick', iconURL: 'https://i.imgur.com/wTF3RuJ.png' });

    const row = new ActionRowBuilder()
      .addComponents(
        new ButtonBuilder()
          .setCustomId('join_queue')
          .setLabel('Join Queue')
          .setStyle(ButtonStyle.Success)
          .setEmoji('✅'),
        new ButtonBuilder()
          .setCustomId('leave_queue')
          .setLabel('Leave Queue')
          .setStyle(ButtonStyle.Danger)
          .setEmoji('❌')
      );

    await channel.send({ embeds: [embed], components: [row] });
  } catch (error) {
    console.error('Error setting up queue message:', error);
  }
};

const joinQueue = async (interaction) => {
  try {
    await interaction.deferReply({ ephemeral: true });

    const user = interaction.user;
    const member = await interaction.guild.members.fetch(user.id);
    if (!queue.includes(user.id) && member.roles.cache.some(role => ['Pug Approved', 'Admin', 'Score Reporter'].includes(role.name))) {
      queue.push(user.id);
      await updateQueueMessage();
      if (queue.length === 10) {
        await createMatch(interaction.guild);
      }
      await interaction.editReply({ content: 'You have joined the queue!' });
    } else {
      await interaction.editReply({ content: 'You are already in the queue or do not have permission to join the queue.' });
    }
  } catch (error) {
    console.error('Error joining queue:', error);
    if (!interaction.replied) {
      await interaction.editReply({ content: 'There was an error joining the queue.' });
    }
  }
};

const leaveQueue = async (interaction) => {
  try {
    await interaction.deferReply({ ephemeral: true });

    const user = interaction.user;
    const index = queue.indexOf(user.id);
    if (index > -1) {
      queue.splice(index, 1);
      await updateQueueMessage();
      await interaction.editReply({ content: 'You have left the queue!' });
    } else {
      await interaction.editReply({ content: 'You are not in the queue!' });
    }
  } catch (error) {
    console.error('Error leaving queue:', error);
    if (!interaction.replied) {
      await interaction.editReply({ content: 'There was an error leaving the queue.' });
    }
  }
};

const updateQueueMessage = async () => {
  try {
    const channel = await client.channels.fetch(process.env.QUEUE_CHANNEL_ID);
    const messages = await channel.messages.fetch({ limit: 10 });
    const queueMessage = messages.find(msg => msg.embeds[0]?.title === '🎮 CSL West Competitive Queue 🎮');

    if (queueMessage) {
      const description = queue.length > 0 
        ? `${queue.map(id => `<@${id}>`).join('\n')}\n\n**(${queue.length}/10)**`
        : 'No one in the queue (0/10)';

      const embed = new EmbedBuilder()
        .setColor('#00ff26')
        .setTitle('🎮 CSL West Competitive Queue 🎮')
        .setDescription(`Use the buttons below to join or leave the queue.\n\n**Current Queue:**\n${description}`)
        .setFooter({ text: 'Powered by Maverick', iconURL: 'https://i.imgur.com/wTF3RuJ.png' });

      const row = new ActionRowBuilder()
        .addComponents(
          new ButtonBuilder()
            .setCustomId('join_queue')
            .setLabel('Join Queue')
            .setStyle(ButtonStyle.Success)
            .setEmoji('✅'),
          new ButtonBuilder()
            .setCustomId('leave_queue')
            .setLabel('Leave Queue')
            .setStyle(ButtonStyle.Danger)
            .setEmoji('❌')
        );

      await queueMessage.edit({ embeds: [embed], components: [row] });
    }
  } catch (error) {
    console.error('Error updating queue message:', error);
  }
};

const createMatch = async (guild) => {
  try {
    const matchCategory = guild.channels.cache.get(process.env.MATCH_CATEGORY_ID);
    const team1Voice = await guild.channels.create({
      name: `Match ${matchCounter} - Team 1`,
      type: ChannelType.GuildVoice,
      parent: matchCategory,
      userLimit: 6,
      permissionOverwrites: [
        {
          id: guild.roles.everyone.id,
          allow: [PermissionsBitField.Flags.Connect],
        },
      ],
    });
    const team2Voice = await guild.channels.create({
      name: `Match ${matchCounter} - Team 2`,
      type: ChannelType.GuildVoice,
      parent: matchCategory,
      userLimit: 6,
      permissionOverwrites: [
        {
          id: guild.roles.everyone.id,
          allow: [PermissionsBitField.Flags.Connect],
        },
      ],
    });
    const matchText = await guild.channels.create({
      name: `match-${matchCounter}`,
      type: ChannelType.GuildText,
      parent: matchCategory,
      permissionOverwrites: [
        {
          id: guild.roles.everyone.id,
          allow: [PermissionsBitField.Flags.ViewChannel, PermissionsBitField.Flags.SendMessages],
        },
      ],
    });

    const team1Captain = queue.shift();
    const team2Captain = queue.shift();
    const remainingPlayers = queue.splice(0, 8);
    const randomMap = maps[Math.floor(Math.random() * maps.length)];
    matches[matchCounter] = {
      team1: [team1Captain],
      team2: [team2Captain],
      remaining: remainingPlayers,
      pickingOrder: ['team1', 'team2', 'team2', 'team1', 'team1', 'team2', 'team1'],
      currentPick: 0,
      mapVotes: {},
      chosenMap: randomMap,
      textChannelId: matchText.id
    };

    saveMatchData();

    console.log(`Match ${matchCounter} created with map ${randomMap}`);

    await updateQueueMessage();
    await updateMatchMessage(matchCounter);

    setTimeout(async () => {
      if (!matches[matchCounter]) return;
      const mostVotedMap = Object.entries(matches[matchCounter].mapVotes)
        .reduce((max, entry) => entry[1] > max[1] ? entry : max, ['', 0])[0];
      if (mostVotedMap) {
        matches[matchCounter].chosenMap = mostVotedMap;
      }
      await updateMatchMessage(matchCounter);
    }, 3 * 60 * 1000);

    matchCounter++;
  } catch (error) {
    console.error('Error creating match:', error);
  }
};

const updateMatchMessage = async (matchNumber) => {
  try {
    const match = matches[matchNumber];
    const matchText = client.channels.cache.get(match.textChannelId);
    if (!matchText) return;

    const team1 = match.team1.map(id => `<@${id}>`).join('\n') || 'No players yet';
    const team2 = match.team2.map(id => `<@${id}>`).join('\n') || 'No players yet';
    const embed = new EmbedBuilder()
      .setTitle(`🎮 Match ${matchNumber} 🎮`)
      .setColor('#ff4500')
      .setDescription('**Match Details**')
      .addFields(
        { name: '🏆 Team 1 Captain', value: `<@${match.team1[0]}>`, inline: true },
        { name: '🏆 Team 2 Captain', value: `<@${match.team2[0]}>`, inline: true },
        { name: '\u200B', value: '\u200B', inline: true },
        { name: '👥 Team 1', value: team1, inline: true },
        { name: '👥 Team 2', value: team2, inline: true },
        { name: '🗺️ Map', value: `**${match.chosenMap}**`, inline: true }
      )
      .setThumbnail('https://i.imgur.com/xfe96CL.png')
      .setImage('https://i.imgur.com/jyuglDa.png')
      .setFooter({ text: 'Powered by Maverick', iconURL: 'https://i.imgur.com/wTF3RuJ.png' })
      .setTimestamp();

    const playerPickRows = [];
    for (let i = 0; i < match.remaining.length; i += 5) {
      const row = new ActionRowBuilder()
        .addComponents(
          await Promise.all(
            match.remaining.slice(i, i + 5).map(async playerId => {
              const member = await client.guilds.cache.get(matchText.guild.id).members.fetch(playerId);
              const nickname = member.nickname || member.user.username;
              return new ButtonBuilder()
                .setCustomId(`pick_${matchNumber}_${playerId}`)
                .setLabel(`Pick ${nickname}`)
                .setStyle(ButtonStyle.Primary);
            })
          )
        );
      playerPickRows.push(row);
    }

    const mapVoteRows = [];
    for (let i = 0; i < maps.length; i += 5) {
      const row = new ActionRowBuilder()
        .addComponents(
          maps.slice(i, i + 5).map(map => new ButtonBuilder()
            .setCustomId(`map_vote_${matchNumber}_${map}`)
            .setLabel(`${map} (${match.mapVotes[map] || 0})`)
            .setStyle(ButtonStyle.Secondary)
          )
        );
      mapVoteRows.push(row);
    }

    const messages = await matchText.messages.fetch({ limit: 10 });
    const matchMessage = messages.find(msg => msg.embeds[0]?.title === `🎮 Match ${matchNumber} 🎮`);
    if (matchMessage) {
      try {
        await matchMessage.delete();
      } catch (error) {
        console.error(`Failed to delete message: ${error.message}`);
      }
    }
    await matchText.send({ embeds: [embed], components: [...playerPickRows, ...mapVoteRows] });
  } catch (error) {
    console.error('Error updating match message:', error);
  }
};

const handleButtonInteraction = async (interaction) => {
  try {
    const customId = interaction.customId;

    if (customId.startsWith('map_vote_')) {
      await voteMap(interaction);
    } else if (customId.startsWith('join_queue')) {
      await joinQueue(interaction);
    } else if (customId.startsWith('leave_queue')) {
      await leaveQueue(interaction);
    } else if (customId.startsWith('pick_')) {
      await handlePick(interaction);
    } else {
      await interaction.reply({ content: 'Unknown button interaction.', ephemeral: true });
    }
  } catch (error) {
    console.error('Error handling button interaction:', error);
    await interaction.reply({ content: 'There was an error handling this button interaction.', ephemeral: true });
  }
};

const handlePick = async (interaction) => {
  try {
    const [_, matchNumber, playerId] = interaction.customId.split('_');
    const match = matches[matchNumber];

    if (!match) {
      await interaction.reply({ content: `Match ${matchNumber} not found.`, ephemeral: true });
      return;
    }

    const user = interaction.user;
    const currentPickTeam = match.pickingOrder[match.currentPick];
    const isCaptain = (user.id === match.team1[0] && currentPickTeam === 'team1') || 
                      (user.id === match.team2[0] && currentPickTeam === 'team2');

    if (!isCaptain) {
      await interaction.reply({ content: 'Only the respective captain can pick for their team on their turn.', ephemeral: true });
      return;
    }

    if (!match.remaining.includes(playerId)) {
      await interaction.reply({ content: 'Invalid player ID for picking.', ephemeral: true });
      return;
    }

    const team = match.pickingOrder[match.currentPick];
    match[team].push(playerId);
    match.remaining = match.remaining.filter(id => id !== playerId);
    match.currentPick++;

    if (match.currentPick === match.pickingOrder.length && match.remaining.length === 1) {
      match.team2.push(match.remaining[0]);
      match.remaining = [];
    }

    await updateMatchMessage(matchNumber);
    await interaction.reply({ content: `Player <@${playerId}> has been picked for ${team === 'team1' ? 'Team 1' : 'Team 2'}.`, ephemeral: true });
  } catch (error) {
    console.error('Error handling pick:', error);
    await interaction.reply({ content: 'There was an error handling the pick.', ephemeral: true });
  }
};

const voteMap = async (interaction) => {
  try {
    const [_, matchNumber, map] = interaction.customId.split('_');
    const userId = interaction.user.id;

    if (!matchNumber || isNaN(matchNumber) || matchNumber < 1) {
      console.error(`Invalid matchNumber: ${matchNumber}`);
      await interaction.reply({ content: 'Invalid match number.', ephemeral: true });
      return;
    }

    const match = matches[matchNumber];
    if (!match) {
      console.error(`Match ${matchNumber} not found.`);
      await interaction.reply({ content: `Match ${matchNumber} not found.`, ephemeral: true });
      return;
    }

    if (!match.mapVotes) match.mapVotes = {};

    if (match.mapVotes[map] && match.mapVotes[map].includes(userId)) {
      await interaction.reply({ content: 'You have already voted for this map.', ephemeral: true });
      return;
    }

    for (const m in match.mapVotes) {
      match.mapVotes[m] = match.mapVotes[m].filter(id => id !== userId);
    }

    if (!match.mapVotes[map]) match.mapVotes[map] = [];
    match.mapVotes[map].push(userId);

    const mostVotedMap = Object.entries(match.mapVotes).reduce((max, entry) => entry[1].length > max[1].length ? entry : max, ['', []])[0];
    match.chosenMap = mostVotedMap;

    await interaction.reply({ content: `Your vote for ${map} has been recorded!`, ephemeral: true });
    await updateMatchMessage(matchNumber);
  } catch (error) {
    console.error('Error voting map:', error);
    await interaction.reply({ content: 'There was an error voting for the map.', ephemeral: true });
  }
};

const findUserMatch = (userId) => {
  for (const [id, match] of Object.entries(matches)) {
    if (match.team1.includes(userId) || match.team2.includes(userId) || match.remaining.includes(userId)) {
      return id;
    }
  }
  return null;
};

const reportCommand = async (message, args) => {
  const roleIds = ['1075756565023445022', '1258877265870192673']; // Array of role IDs
  const hasAdminPermission = message.member.permissions.has(PermissionsBitField.Flags.Administrator);
  const hasRequiredRole = roleIds.some(roleId => message.member.roles.cache.has(roleId));

  const hasPermission = hasAdminPermission || hasRequiredRole; // Check for permissions

  let matchId = Object.keys(matches).find(id => matches[id].textChannelId === message.channel.id);

  if (!matchId && hasPermission) {
    matchId = args[0];
  }

  if (!matchId || !matches[matchId]) {
    return message.reply('Invalid match ID or no active match found.');
  }

  try {
    const winningTeamNumber = hasPermission ? args[1] : args[0];
    const match = matches[matchId];
    const team1 = match.team1;
    const team2 = match.team2;
    let winningTeam, losingTeam;

    if (winningTeamNumber === '1') {
      winningTeam = team1;
      losingTeam = team2;
      updateElo(team1, team2);
      updateStats(team1, team2, match.chosenMap, true);
    } else if (winningTeamNumber === '2') {
      winningTeam = team2;
      losingTeam = team1;
      updateElo(team2, team1);
      updateStats(team2, team1, match.chosenMap, true);
    } else {
      return message.reply('Invalid winning team.');
    }

    await message.reply(`Match ${matchId} has been reported and the channels will be deleted.`);

    const guild = message.guild;
    const matchCategory = await guild.channels.fetch(process.env.MATCH_CATEGORY_ID);
    const team1Voice = matchCategory.children.cache.find(c => c.name === `Match ${matchId} - Team 1`);
    const team2Voice = matchCategory.children.cache.find(c => c.name === `Match ${matchId} - Team 2`);
    const matchText = matchCategory.children.cache.find(c => c.name === `match-${matchId}`);
    if (team1Voice) await team1Voice.delete();
    if (team2Voice) await team2Voice.delete();
    if (matchText) await matchText.delete();

    delete matches[matchId];
    saveMatchData();

    const reporter = message.author;
    logMatch(matchId, winningTeam, losingTeam, `Team ${winningTeamNumber}`, reporter);
  } catch (error) {
    console.error('Error reporting match:', error);
    message.reply('There was an error reporting the match.');
  }
};

const updateStats = (winningTeam, losingTeam, map, isWin) => {
  [...winningTeam, ...losingTeam].forEach(player => {
    if (!playerStats[player]) playerStats[player] = { BW: { wins: 0, losses: 0 }, PORT: { wins: 0, losses: 0 }, ANK: { wins: 0, losses: 0 }, COMP: { wins: 0, losses: 0 }, SB: { wins: 0, losses: 0 }, MEX: { wins: 0, losses: 0 }, EE: { wins: 0, losses: 0 } };

    if (winningTeam.includes(player)) {
      playerStats[player][map].wins++;
    } else {
      playerStats[player][map].losses++;
    }
  });

  saveData();
};

const clearQueueCommand = async (message) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    queue = [];
    await updateQueueMessage();
    message.reply('The queue has been cleared.');
  } catch (error) {
    console.error('Error clearing queue:', error);
    message.reply('There was an error clearing the queue.');
  }
};

const resetEloCommand = async (message) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    playersELO = {};
    saveData();
    message.reply('All ELO has been reset.');
  } catch (error) {
    console.error('Error resetting ELO:', error);
    message.reply('There was an error resetting the ELO.');
  }
};

const warningResetCommand = async (message) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    playerWarnings = {};
    saveData();
    message.reply('All warnings have been reset.');
  } catch (error) {
    console.error('Error resetting warnings:', error);
    message.reply('There was an error resetting the warnings.');
  }
};

const setMatchLogChannelCommand = async (message, args) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    const channelId = args[0];
    process.env.MATCH_LOG_CHANNEL_ID = channelId;
    message.reply('Match log channel set.');
  } catch (error) {
    console.error('Error setting match log channel:', error);
    message.reply('There was an error setting the match log channel.');
  }
};

const giveEloCommand = async (message, args) => {
  if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) {
    return message.reply('You do not have permission to use this command.');
  }

  try {
    const userId = args[0].replace('<@', '').replace('>', '');
    const eloChange = parseInt(args[1], 10);

    if (!playersELO[userId]) playersELO[userId] = 0;
    playersELO[userId] += eloChange;

    saveData();
    message.reply(`ELO for <@${userId}> has been changed by ${eloChange}. New ELO: ${playersELO[userId]}`);
  } catch (error) {
    console.error('Error giving ELO:', error);
    message.reply('There was an error changing the ELO.');
  }
};
 # dd if=shared.disk-image.img of=/dev/XXX bs=1M oflag=direct,sync status=progress
star

Fri Jul 12 2024 10:59:19 GMT+0000 (Coordinated Universal Time) https://maticz.com/enterprise-blockchain-development

@Ameliasebastian #enterpriseblockchain development

star

Fri Jul 12 2024 10:30:32 GMT+0000 (Coordinated Universal Time) https://maticz.com/binance-clone-script

@jamielucas #drupal

star

Fri Jul 12 2024 10:19:41 GMT+0000 (Coordinated Universal Time) https://maticz.com/ai-development-services

@carolinemax ##maticz ##usa #ai_development_company #ai_software_development

star

Fri Jul 12 2024 10:15:10 GMT+0000 (Coordinated Universal Time)

@Ranjith

star

Fri Jul 12 2024 10:09:46 GMT+0000 (Coordinated Universal Time)

@Ranjith

star

Fri Jul 12 2024 09:37:11 GMT+0000 (Coordinated Universal Time)

@signup

star

Fri Jul 12 2024 06:42:51 GMT+0000 (Coordinated Universal Time)

@StephenThevar #elasticsearch

star

Fri Jul 12 2024 02:13:42 GMT+0000 (Coordinated Universal Time)

@davidmchale #call() #object

star

Fri Jul 12 2024 00:25:30 GMT+0000 (Coordinated Universal Time) https://tow-boot.org/devices/libreComputer-rocRk3399PcMezzanine.html

@Dewaldt

star

Thu Jul 11 2024 21:37:54 GMT+0000 (Coordinated Universal Time) https://www.makeuseof.com/windows-d3d11-gpu-error/

@mosk_1990

star

Thu Jul 11 2024 20:58:13 GMT+0000 (Coordinated Universal Time)

@wasim_mm1

star

Thu Jul 11 2024 19:37:44 GMT+0000 (Coordinated Universal Time) https://activescienceparts.com/how-many-ribs-do-males-and-females-have/

@darkwebmarket

star

Thu Jul 11 2024 19:11:39 GMT+0000 (Coordinated Universal Time) https://www.w3schools.com/react/tryit.asp?filename

@Black_Shadow #javascript #react.js #html #output #text

star

Thu Jul 11 2024 19:07:48 GMT+0000 (Coordinated Universal Time) https://www.w3schools.com/react/tryit.asp?filename

@Black_Shadow #react.js #javascript #html

star

Thu Jul 11 2024 18:57:24 GMT+0000 (Coordinated Universal Time)

@werlang #javascript

star

Thu Jul 11 2024 18:51:03 GMT+0000 (Coordinated Universal Time) http://127.0.0.1:4111/

@gyg85nax

star

Thu Jul 11 2024 18:49:25 GMT+0000 (Coordinated Universal Time)

@webisko #css

star

Thu Jul 11 2024 18:17:42 GMT+0000 (Coordinated Universal Time)

@iamkatmakhafola

star

Thu Jul 11 2024 18:10:43 GMT+0000 (Coordinated Universal Time) https://www.vinjegaard.com/tutorial/lenis-smooth-scroll-in-elementor

@webisko #javascript

star

Thu Jul 11 2024 17:47:23 GMT+0000 (Coordinated Universal Time)

@gbritgs

star

Thu Jul 11 2024 17:14:27 GMT+0000 (Coordinated Universal Time)

@webisko #css

star

Thu Jul 11 2024 15:37:50 GMT+0000 (Coordinated Universal Time) http://goatgames.unaux.com/wp-admin/admin.php?page

@rajat #undefined

star

Thu Jul 11 2024 15:30:23 GMT+0000 (Coordinated Universal Time)

@dorado #c

star

Thu Jul 11 2024 15:30:23 GMT+0000 (Coordinated Universal Time) http://goatgames.unaux.com/wp-admin/admin.php?page

@rajat #undefined

star

Thu Jul 11 2024 15:29:44 GMT+0000 (Coordinated Universal Time) http://goatgames.unaux.com/wp-admin/admin.php?page

@rajat #undefined

star

Thu Jul 11 2024 15:29:17 GMT+0000 (Coordinated Universal Time) http://goatgames.unaux.com/wp-admin/admin.php?page

@rajat #undefined

star

Thu Jul 11 2024 15:23:46 GMT+0000 (Coordinated Universal Time)

@roamtravel

star

Thu Jul 11 2024 14:21:01 GMT+0000 (Coordinated Universal Time)

@tokoyami_ds

star

Thu Jul 11 2024 14:00:50 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#usb-device-boot-mode

@Dewaldt

star

Thu Jul 11 2024 13:58:46 GMT+0000 (Coordinated Universal Time)

@Justus

star

Thu Jul 11 2024 13:31:10 GMT+0000 (Coordinated Universal Time)

@roamtravel

star

Thu Jul 11 2024 12:51:07 GMT+0000 (Coordinated Universal Time)

@roamtravel

star

Thu Jul 11 2024 12:19:37 GMT+0000 (Coordinated Universal Time)

@FRTZ

star

Thu Jul 11 2024 12:16:59 GMT+0000 (Coordinated Universal Time) https://linuxsimply.com/linux-basics/package-management/repository-list/apt/

@Spsypg

star

Thu Jul 11 2024 12:15:50 GMT+0000 (Coordinated Universal Time) https://linuxsimply.com/linux-basics/package-management/repository-list/apt/

@Spsypg

star

Thu Jul 11 2024 12:08:24 GMT+0000 (Coordinated Universal Time)

@RehmatAli2024 #deluge

star

Thu Jul 11 2024 12:05:09 GMT+0000 (Coordinated Universal Time) https://linuxsimply.com/linux-basics/package-management/repository-list/apt/

@Spsypg

star

Thu Jul 11 2024 11:36:58 GMT+0000 (Coordinated Universal Time) https://askubuntu.com/questions/519154/how-to-solve-the-error-warningrootcould-not-open-file-etc-apt-sources-list

@Spsypg

star

Thu Jul 11 2024 11:35:28 GMT+0000 (Coordinated Universal Time) https://askubuntu.com/questions/519154/how-to-solve-the-error-warningrootcould-not-open-file-etc-apt-sources-list

@Spsypg

star

Thu Jul 11 2024 11:32:19 GMT+0000 (Coordinated Universal Time) https://askubuntu.com/questions/519154/how-to-solve-the-error-warningrootcould-not-open-file-etc-apt-sources-list

@Spsypg

star

Thu Jul 11 2024 11:30:17 GMT+0000 (Coordinated Universal Time) https://www.kali.org/docs/wsl/wsl-preparations/

@Dewaldt

star

Thu Jul 11 2024 10:53:25 GMT+0000 (Coordinated Universal Time) https://superuser.com/questions/647927/install-windows-store-app-package-appx-for-all-users

@See182

star

Thu Jul 11 2024 10:35:23 GMT+0000 (Coordinated Universal Time) https://playhop.com/app/287417?utm_source

@gamersac100

star

Thu Jul 11 2024 10:28:07 GMT+0000 (Coordinated Universal Time)

@FRTZ

star

Thu Jul 11 2024 10:27:48 GMT+0000 (Coordinated Universal Time) https://www.kali.org/blog/kali-linux-in-the-windows-app-store/

@Dewaldt

star

Thu Jul 11 2024 10:27:13 GMT+0000 (Coordinated Universal Time)

@FRTZ

star

Thu Jul 11 2024 10:20:59 GMT+0000 (Coordinated Universal Time) https://chromewebstore.google.com/detail/save-code/annlhfjgbkfmbbejkbdpgbmpbcjnehbb?hl

@screh

star

Thu Jul 11 2024 10:08:03 GMT+0000 (Coordinated Universal Time) https://tow-boot.org/devices/pine64-pinephonePro.html

@Dewaldt

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension