#!/usr/bin/env python
# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod
from bson.binary import Binary
import math
import pickle

import numpy
import six

@six.add_metaclass(ABCMeta)
class PoolInterface():
    """
    Pool interface defintion

    """
    @abstractmethod
    def add(self, state, action, reward, next_state, done,
            next_actions=None, priority=1):
        """
        Pool is used to store experience data, like:
          (state, action, reward, next_state). It must contains 4 things :
            state: state of environment
            action: executed action with given state
            reward: feedback of action with given state
            next_state: next state of environment after executing action
        These 2 things is optional:
            next_actions: available actions of next state
            priority: priority (loss) of this record
        """
        pass

    @abstractmethod
    def remove(self, record_id):
        """
        Remove record from pool with record_id
        """
        pass

    @abstractmethod
    def sample(self, size):
        """
        Sample records from pool with given size.
        """
        pass

    @abstractmethod
    def update(self, priorities):
        """
        Update each records' priority
        """
        pass

    @abstractmethod
    def size(self):
        """
        Get size of current pool
        """
        pass

    @abstractmethod
    def amount(self):
        """
        Get number of records in pool
        """
        pass

    @abstractmethod
    def all(self):
        """
        Get all experiences of pool by generator
        """
        pass

class MemoryPool(PoolInterface):
    """
    MemoryPool uses `dict` to store experience data. Data can be sampled
    after it add to pool. Sample method is biased random sampling with
    priority.

    Args:
        pool_size (int): sepcify size of memory pool. `0` for unlimited
            (default: 0)

    Returns:
        MemoryPool object

    Examples:
        # Init pool
        >>> mpool = MemoryPool(3000)
        # Add data to pool
        >>> mpool.add(
                state=[1, 2, 3], action=3, reward=100, next_state=[4, 5, 6]
            )
        # Sample data for training
        >>> records = mpool.sample(30)
        >>> print(len(records))
        30
        # Update priority of data
        >>> priorities = [(key1, 10), (key2, 0), (key3, 9), ...]
        >>> mpool.update(priorities)
    """

    def __init__(self, pool_size=0):
        if isinstance(pool_size, int):
            if pool_size < 0:
                raise TypeError("Pool size should be positive integer")
            self._size = pool_size

        self._experiences = {}
        self._q_front = 0

    def add(self, state, action, reward, next_state, done,
            next_actions=None, priority=1, info=None):
        """
        Add new data to experience pool.

        Args:
            state: any type as long as it can describe the state of environment
            action: any type as long as it can represent executed action with
                above state
            reward: also free type for action feedback
            next_state: Like state but it is for describing next state
            next_actions: For next state's actions (Default: None),
            priority: It specify the priority of data (Default: 0)

        Returns:
            amount: record number in pool

        Examples:
            >>> mpool.add(
                    state=[0, 0, 1], action=1,
                    reward=100, next_state=[1, 0, 0]
                )
            >>> mpool.add(
                    state={'a': 1, 'b': 0}, action=3,
                    reward=-1, next_state={'a': -1, 'b': 1},
                    next_actions=[3, 1, 0], priority=3.5
                )

        """
        if numpy.isnan(priority):
            priority = 1e-3
        elif priority < 1e-3:
            priority = 1e-3
        elif priority > 1e+3:
            priority = 1e+3

        if self._q_front > six.MAXSIZE:
            self._q_front = 0

        while self._q_front in self._experiences:
            self._q_front += 1

        self._experiences[self._q_front] = {
            'state': state,
            'action': action,
            'reward': reward,
            'next_state': next_state,
            'next_actions': next_actions,
            'done': done,
            'priority': priority,
            'info': info,
        }

        if self.amount() > self.size() > 0:
            min_p = 1e+9
            min_key = 0
            for key, record in self._experiences.items():
                if record['priority'] < min_p:
                    min_p = record['priority']
                    min_key = key
            self.remove(min_key)
        return self.amount()

    def remove(self, key):
        """
        Remove record from pool with key.

        Args:
            key: the key of record in dictionary

        Returns:
            None

        Examples:
            # Remove 100th data in pool
            >>> pool.remove(100)

        """
        return self._experiences.pop(key)

    def sample(self, size):
        """
        Sample records from pool with given size.

        Args:
            size (int): sampling size

        Returns:
            samples (list):
                [
                (index, {'state': ..., 'action': ..., 'reward': ...,
                 'next_state': ..., 'next_actions': ..., 'priority': ...,}),
                (...),
                ]

        Examples:
            # Biased random sampling 100 records
            >>> pool.sample(100)

        """
        dist = []
        keys = []
        for k, record in self._experiences.items():
            dist.append(record['priority'])
            keys.append(k)

        sum_d = float(sum(dist))
        prob = [item / sum_d for item in dist]

        if size > 0:
            if size > self.amount():
                size = self.amount()
            keys = numpy.random.choice(
                keys, size=size, p=prob, replace=False
            )
        else:
            keys = []

        for k in keys:
            yield k, self._experiences[k]

    def update(self, priorities):
        """
        Update each records' priority

        Args:
            priorities (list):
                [
                 (index, priority),
                 (...),
                 ...
                ]

        Returns:
            None

        Examples:
            >>> pool.update([
                    (0, 10),
                    (1, 0),
                    (2, 3)
                ])

        """
        for key, priority in priorities:
            if numpy.isnan(priority):
                p = 1e-3
            elif priority < 1e-3:
                p = 1e-3
            elif priority > 1e+3:
                p = 1e+3
            else:
                p = priority

            try:
                self._experiences[key]['priority'] = p
            except:
                pass

    def size(self):
        """
        Get size of current pool

        Args:
            None

        Returns:
            pool_size (int): limited size of pool

        Examples:
            >>> mpool = MemoryPool(300)
            >>> print(mpool.size())
            300

        """
        return self._size

    def amount(self):
        """
        Get number of records in pool

        Args:
            None

        Returns:
            number (int): number of records

        Examples:
            >>> mpool = MemoryPool(300)
            >>> print(mpool.size())
            300
            >>> print(mpool.amount())
            0
            >>> mpool.add(1, 2, 3, 4)
            >>> print(mpool.amount())
            1

        """
        return len(self._experiences)

    def all(self):
        """
        Get all experiences of pool by generator

        Args:
            None

        Returns:
            record (dict): experience record

        Examples:
            >>> mpool = MemoryPool(300)
            >>> for item in mpool.all():
                    print(item)
            {'state': ...}
            {'state': ...}
            ...

        """
        for key, record in self._experiences.items():
            yield key, record

class MongoPool(PoolInterface):
    """
    MongoPool store experience data to db. Data must be numpy array.

    Args:
        collection (pymongo.collection.Collection): Specific collection for
            storing experience data
        pool_size (int): sepcify size of pool. `0` for unlimited
            (default: 0)

    Returns:
        MongoPool object

    Examples:
        # Init pool
        >>> client = MongoClient()
        >>> mpool = MongoPool(client['DB']['Collection'])
        # Add data to pool
        >>> mpool.add(
                state=[1, 2, 3], action=3, reward=100, next_state=[4, 5, 6]
            )
        # Sample data for training
        >>> records = mpool.sample(30)
        >>> print(len(records))
        30
        # Update priority of data
        >>> priorities = [(id1, 10), (id2, 0), (id3, 9), ...]
        >>> mpool.update(priorities)
    """

    def __init__(self, collection, pool_size=0):
        if isinstance(pool_size, int):
            if pool_size < 0:
                raise TypeError("Pool size should be positive integer")
            self._size = pool_size

        self._collection = collection

    def add(self, state, action, reward, next_state, done,
            next_actions=None, priority=1, info=None):
        """
        Add new data to experience pool.

        Args:
            state: any type as long as it can describe the state of environment
            action: any type as long as it can represent executed action with
                above state
            reward: also free type for action feedback
            next_state: Like state but it is for describing next state
            next_actions: For next state's actions (Default: None),
            priority: It specify the priority of data (Default: 0)

        Returns:
            amount: record number in pool

        Examples:
            >>> mpool.add(
                    state=[0, 0, 1], action=1,
                    reward=100, next_state=[1, 0, 0]
                )
            >>> mpool.add(
                    state={'a': 1, 'b': 0}, action=3,
                    reward=-1, next_state={'a': -1, 'b': 1},
                    next_actions=[3, 1, 0], priority=3.5
                )

        """
        if numpy.isnan(priority):
            priority = 1e-3
        elif priority < 1e-3:
            priority = 1e-3
        elif priority > 1e+3:
            priority = 1e+3

        last_record = self._get_last()
        if last_record:
            index = last_record['index'] + 1
        else:
            index = 0

        data = {
            'index': index,
            'state': Binary(pickle.dumps(state)),
            'action': Binary(pickle.dumps(action)),
            'reward': Binary(pickle.dumps(reward)),
            'next_state': Binary(pickle.dumps(next_state)),
            'next_actions': Binary(pickle.dumps(next_actions)),
            'done': done,
            'priority': priority,
            'info': info,
        }

        self._collection.insert_one(data)
        if self.amount() > self.size() > 0:
            min_p = 1e+9
            min_index = 0
            for i, record in enumerate(self._experiences):
                if record['priority'] < min_p:
                    min_p = record['priority']
                    min_index = i
            self.remove(min_index)
        return self.amount()

    def remove(self, record_id):
        """
        Remove record from pool with record_id.

        Args:
            record_id: the index of data

        Returns:
            None

        Examples:
            # Remove 100th data in pool
            >>> pool.remove(100)

        """
        self._collection.remove({'index': record_id})

    def sample(self, size):
        """
        Sample records from pool with given size.

        Args:
            size (int): sampling size

        Returns:
            samples (list):
                [
                (index, {'state': ..., 'action': ..., 'reward': ...,
                 'next_state': ..., 'next_actions': ..., 'priority': ...,}),
                (...),
                ]

        Examples:
            # Biased random sampling 100 records
            >>> pool.sample(100)

        """
        dist = []
        indexes = []
        for record in self._collection.find({}, {'index': 1, 'priority': 1}):
            dist.append(record['priority'])
            indexes.append(record['index'])

        sum_d = float(sum(dist))
        prob = [item / sum_d for item in dist]

        if size > 0 and indexes:
            if size > len(indexes):
                size = len(indexes)

            indexes = numpy.random.choice(
                indexes,
                size=size, p=prob, replace=False
            )
            indexes = indexes.tolist()
        else:
            indexes = []

        samples = list()
        for record in self._collection.find({'index': {'$in': indexes}}):
            record['state'] = pickle.loads(record['state'])
            record['action'] = pickle.loads(record['action'])
            record['reward'] = pickle.loads(record['reward'])
            record['next_state'] = pickle.loads(record['next_state'])
            record['next_actions'] = pickle.loads(record['next_actions'])
            samples.append((record['index'], record))
        return samples

    def update(self, priorities):
        """
        Update each records' priority

        Args:
            priorities (list):
                [
                 (index, priority),
                 (...),
                 ...
                ]

        Returns:
            None

        Examples:
            >>> pool.update([
                    (0, 10),
                    (1, 0),
                    (2, 3)
                ])

        """
        for index, priority in priorities:
            if numpy.isnan(priority):
                p = 1e-3
            elif priority < 1e-3:
                p = 1e-3
            elif priority > 1e+3:
                p = 1e+3
            else:
                p = priority

            self._collection.update_one(
                {"index": index}, {"$set": {"priority": p}}
            )

    def size(self):
        """
        Get size of current pool

        Args:
            None

        Returns:
            pool_size (int): limited size of pool

        Examples:
            >>> mpool = MemoryPool(300)
            >>> print(mpool.size())
            300

        """
        return self._size

    def amount(self):
        """
        Get number of records in pool

        Args:
            None

        Returns:
            number (int): number of records

        Examples:
            >>> mpool = MemoryPool(300)
            >>> print(mpool.size())
            300
            >>> print(mpool.amount())
            0
            >>> mpool.add(1, 2, 3, 4)
            >>> print(mpool.amount())
            1

        """
        return self._collection.count()

    def all(self):
        """
        Get all experiences of pool by generator

        Args:
            None

        Returns:
            record (dict): experience record

        Examples:
            >>> mpool = MemoryPool(300)
            >>> for item in mpool.all():
                    print(item)
            {'state': ...}
            {'state': ...}
            ...

        """
        condition = {"$query": {}, "$orderby": {"id": 1}}
        for record in self._collection.find(condition):
            record['state'] = pickle.loads(record['state'])
            record['action'] = pickle.loads(record['action'])
            record['reward'] = pickle.loads(record['reward'])
            record['next_state'] = pickle.loads(record['next_state'])
            record['next_actions'] = pickle.loads(record['next_actions'])
            yield record

    def _get_last(self):
        condition = {"$query": {}, "$orderby": {"index": -1}}
        return self._collection.find_one(condition)


import os
import discord
import random

def randnum(fname):
	lines=open(fname).read().splitlines()
	return random.choice(lines)

client = discord.Client()

@client.event
async def on_ready():
    print('We have logged in as {0.user}'.format(client))

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content.startswith('$roadman'):
        await message.channel.send(randnum('quotes.txt'))

client.run(os.getenv('TOKEN'))


# -*- coding: utf-8 -*-
# @Author: Arius
# @Email: arius@qq.com
# @Date:   2019-01-23 21:48:15

from pypika import (
    Query,
    Table,
    Tables,
    Field,
    Order,
    functions as fn,
)
import time

from auth.aes import sha1
from config import tables as cfg

def sql_fmt(func):
    def wrap(self, *args, **kwargs):
        res = func(self, *args, **kwargs)
        return res.get_sql().replace('"', '`')
    return wrap

class SqlBuilder(object):

    @sql_fmt
    def login(name, pwd, arr):
        usr = Table(cfg.usr)
        q = Query.from_(usr).select(
                *arr
            ).where(
                usr.name == name
            ).where(
                usr.pwd == pwd
            )
        return q

    @sql_fmt
    def register(name, pwd):
        usr = Table(cfg.usr)
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        q = Query.into(usr).columns(
            usr.name, usr.pwd, usr.created, usr.updated
        ).insert(
            name, pwd, now, now
        )
        return q

    @sql_fmt
    def get_usr(id):
        usr = Table(cfg.usr)
        q = Query.from_(usr).select(
            usr.id, usr.name
        ).where(
            usr.id == id
        )
        return q

    @sql_fmt
    def check_exist_by_name(name):
        usr = Table(cfg.usr)
        q = Query.from_(usr).select(
            fn.Count(usr.id)
        ).where(
            usr.name == name
        )
        return q

    @sql_fmt
    def check_exist(id):
        usr = Table(cfg.usr)
        q = Query.from_(usr).select(
            fn.Count(usr.id)
        ).where(
            usr.id == id
        )
        return q

    @sql_fmt
    def update_usr(id, pwd, last_ip):
        usr = Table(cfg.usr)
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        q = Query.update(usr).set(
            usr.pwd, pwd or usr.pwd
        ).set(
            usr.update, now
        ).set(
            usr.last_ip, last_ip or usr.last_ip
        ).where(
            usr.id == id
        )
        return q

    @sql_fmt
    def create_room(name, owner):
        room = Table(cfg.room)
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        q = Query.into(room).columns(
                room.name, room.owner, room.updated, room.created
            ).insert(
                name, owner, now, now
            )
        return q

    @sql_fmt
    def join_room(room, member):
        join = Table(cfg.join)
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        if isinstance(member, list):
            q = Query.into(join).columns(
                join.room, join.member, join.created
            )
            for m in member:
                q = q.insert(room, m, now)
        else:
            q = Query.into(join).columns(
                join.room, join.member, join.created
            ).insert(
                room, member, now
            )
        return q

    @sql_fmt
    def remove_member(room, member):
        join = Table(cfg.join)
        q = Query.from_(join).delete().where(
            (join.room == room) & (join.member == member)
        )
        return q

    @sql_fmt
    def get_room(id):
        room = Table(cfg.room)
        q = Query.from_(room).select(
            room.id, room.name, room.owner
        ).where(
            room.id == id
        )
        return q

    @sql_fmt
    def update_room(id, name, owner):
        room = Table(cfg.room)
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        q = Query.update(room).set(
            room.name, name or room.name
        ).set(
            room.updated, now
        ).set(
            room.owner, owner or room.owner
        ).where(
            room.id == id
        )
        return q

    @sql_fmt
    def check_room_owner(id, owner):
        room = Table(cfg.room)
        q = Query.from_(room).select(
            fn.Count(room.id)
        ).where(
            (room.id == id) & (room.owner == owner)
        )
        return q

    @sql_fmt
    def check_room_join(room, member):
        join = Table(cfg.join)
        q = Query.from_(join).select(
            fn.Count(join.id)
        ).where(
            (join.room == room) & (join.member == member)
        )
        return q

    @sql_fmt
    def get_all_room(member):
        join, room = Tables(cfg.join, cfg.room)
        q = Query.from_(join).join(
            room
        ).on(
            join.room == room.id
        ).select(
            join.room, room.name
        ).where(
            join.member == member
        )
        return q

    @sql_fmt
    def get_all_roommate(room):
        join, usr = Tables(cfg.join, cfg.usr)
        join = Table(cfg.join)
        q = Query.from_(join).select(
            join.member
        ).where(
            join.room == room
        )
        return q

    @sql_fmt
    def get_all_roommate_info(room):
        join, usr = Tables(cfg.join, cfg.usr)
        q = Query.from_(usr).join(
            join
        ).on(
            join.member == usr.id
        ).select(
            usr.id, usr.name
        ).where(
            join.room == room
        )
        return q

    @sql_fmt
    def search(key):
        room, usr = Tables(cfg.room, cfg.usr)
        q = Query.from_(room).select(
            room.id, room.name, fn.Concat(1).as_('type')
        ).where(
            room.name.like(key + '%')
        ) + Query.from_(usr).select(
            usr.id, usr.name, fn.Concat(0).as_('type')
        ).where(
            usr.name.like(key + '%')
        )
        return q

    @sql_fmt
    def searchUsr(key):
        usr = Table(cfg.usr)
        q = Query.from_(usr).select(
            usr.id, usr.name
        ).where(
            usr.name == key
        )
        return q

if __name__ == '__main__':
    # print (SqlBuilder.register('aaa', 'bbb'))
    # print (SqlBuilder.update_usr(1, None, 'localhost'))
    # print (SqlBuilder.create_room(10003))
    print (SqlBuilder.join_room(2, 10003))
    # print (SqlBuilder.get_all_roommate(2))
    # print (SqlBuilder.check_room_join(2, 10003))
    # print (SqlBuilder.check_room_owner(2, 10003))
    # print (SqlBuilder.check_exist(10003))


#Deobfuscator by HuyAnh
#Zalo:0905491417
#fb.com/huyanhnong.21
luc = "\033[1;32m"

trang = "\033[1;37m"

do = "\033[1;31m"

vang = "\033[0;93m"

hong = "\033[1;35m"

xduong = "\033[1;34m"

xnhac = "\033[1;36m"

# Đánh Dấu Bản Quyền

ndp_tool = do + "[" + trang + "=.=" + do + "] " + trang + "=> "

ndp = do + "[" + trang + "=.=" + do + "] " + trang + "=> "

# Config

# List Dữ Liệu

list_id_name_page = []

# Import Lib

import requests, threading

import os, sys

from time import sleep

from datetime import datetime

import json

try:

	import requests,pystyle

except:

	print (luc + "Bạn Chưa Tải Thư Viện \n Bắt Đầu Tải ")

	os.system('pip install requests && pip install bs4 && pip install pystyle')

# ==========================[ FUNCTION ]===========================================

def echo(a):

   for i in range(len(a)):

     sys.stdout.write(a[i])

     sys.stdout.flush()

     sleep(0.001)

   print()

def banner():

    banner = f"""\033[1;34m

\033[1;32m

\033[1;32m            ███████╗██╗   ██╗████████╗██╗  ██╗

\033[1;32m            ╚══███╔╝╚██╗ ██╔╝╚══██╔══╝██║  ██║

\033[1;32m              ███╔╝  ╚████╔╝    ██║   ███████║

\033[1;32m             ███╔╝    ╚██╔╝     ██║   ██╔══██║

\033[1;32m            ███████╗   ██║      ██║   ██║  ██║

\033[1;32m            ╚══════╝   ╚═╝      ╚═╝   ╚═╝  ╚═╝ Tool Kích Hoạt Page Facebook Bị Ẩn/Huỷ Đăng

\033[1;39m              ⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦

\033[1;31m Nguyễn Ngọc Thành                  DevOps: Lê Trọng Truyền

\033[1;39m              ⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦⏦

"""

    echo(banner)

def clear():

    os.system("cls" if os.name == "nt" else "clear")

def thanh():

    print('\033[1;37m- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -')

def ndp_delay(o):

    while o > 1:

        o = o - 1

        print(f'{trang}[\033[1;31mZ\033[1;33my\033[1;36mt\033[1;35mh\033[1;34m]\033[1;37m[\033[1;36m|\033[1;37m]\033[1;37m[.....]\033[1;37m[{o}]', '     ', end='\r')

        sleep(1/6)

        print(f'{trang}[\033[1;35mZ\033[1;32my\033[1;34mt\033[1;35mh\033[1;36m]\033[1;37m[\033[1;31m/\033[1;37m]\033[1;37m[\033[1;32m>\033[1;37m....]\033[1;37m[{o}]', '     ', end='\r')

        sleep(1/6)

        print(f'{trang}[\033[1;31mZ\033[1;33my\033[1;36mt\033[1;35mh\033[1;34m]\033[1;37m[\033[1;32m-\033[1;37m]\033[1;37m[\033[1;32m>\033[1;31m>\033[1;37m...]\033[1;37m[{o}]', '     ', end='\r')

        sleep(1/6)

        print(f'{trang}[\033[1;35mZ\033[1;32my\033[1;34mt\033[1;35mh\033[1;36m]\033[1;37m[\033[1;33m+\033[1;37m]\033[1;37m[\033[1;32m>\033[1;31m>\033[1;36m>\033[1;37m..]\033[1;37m[{o}]', '     ', end='\r')

        sleep(1/6)

        print(f'{trang}[\033[1;31mZ\033[1;33my\033[1;36mt\033[1;35mh\033[1;34m]\033[1;37m[\033[1;34m\\{trang}]\033[1;37m[\033[1;32m>\033[1;31m>\033[1;36m>\033[1;33m>\033[1;37m.]\033[1;37m[{o}]', '     ', end='\r')

        sleep(1/6)

        print(f'{trang}[\033[1;35mZ\033[1;32my\033[1;34mt\033[1;35mh\033[1;36m]\033[1;37m[\033[1;35m|\033[1;37m]\033[1;37m[\033[1;32m>\033[1;31m>\033[1;36m>\033[1;33m>\033[1;35m>\033[1;37m]\033[1;37m[{o}]', '     ', end='\r')

        sleep(1/6)

def rungr(x):

    time = datetime.now().strftime("%H:%M:%S")

    uid_page = list_id_name_page[x].split('|')[0]

    name_page = list_id_name_page[x].split('|')[1]

    list1 = (f'i_user={uid_page};')

    cookie9 = (f'{cookie}{list1}')

    headers = {

        'Authority': 'www.facebook.com',

        'Method': 'POST',

        'Path': '/api/graphql/',

        'Scheme': 'https',

        'Accept': '*/*',

        'Accept-Language': 'vi,en;q=0.9,en-GB;q=0.8,en-US;q=0.7',

        'Content-Length': '1704',

        'Content-Type': 'application/x-www-form-urlencoded',

        'Cookie': cookie9,

        'Origin': 'https://www.facebook.com',

        'Referer': 'https://www.facebook.com/pages/?category=your_pages&ref=bookmarks',

        'Sec-Ch-Prefers-Color-Scheme': 'dark',

        'Sec-Ch-Ua': '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"',

        'Sec-Ch-Ua-Full-Version-List': '"Not.A/Brand";v="8.0.0.0", "Chromium";v="114.0.5735.201", "Microsoft Edge";v="114.0.1823.67"',

        'Sec-Ch-Ua-Mobile': '?0',

        'Sec-Ch-Ua-Platform': '"Windows"',

        'Sec-Ch-Ua-Platform-Version': '"15.0.0"',

        'Sec-Fetch-Dest': 'empty',

        'Sec-Fetch-Mode': 'cors',

        'Sec-Fetch-Site': 'same-origin',

        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67',

        'X-Asbd-Id': '129477',

        'X-Fb-Friendly-Name': 'usePagesCometEditPageVisibilityMutation',

        'X-Fb-Lsd': 'MsxoFWxSNp7G_6piXo7vFV',

    }

    data = {

        'av': idpro5,

        '__user': idpro5,

        '__a': '1',

        '__req': '12',

        '__hs': '19540.HYP:comet_pkg.2.1..2.1',

        'dpr': '1.5',

        '__ccg': 'EXCELLENT',

        '__rev': '1007781546',

        '__s': 'hrh3k2:l8nej4:wsrxa9',

        '__hsi': '7251274423764571025',

        '__dyn': '7AzHJ16UW5Eb8ng5K8G6EjBWobVo66u2i5U4e2C17xt3odEnz8K361twYwJyE24wJwpUe8hwaG0Z82_CxS320om78bbwto88422y11xmfz81s8hwGxu782lwv89kbxS2218wc61axe3S7Udo5qfK0zEkxe2GewyDwkUtxGm2SUbElxm3y3aexfxmu3W3y261eBx_y88E3qxWm2CVEbUGdG1FyEeo88cA0z8c86-3u364UrwFg662S269wqQ1Fw',

        '__csr': 'gZ2tjhkl6Jjl8zih15dkGOsnsl9vOTZAW9OjPYRil9QhOli9llTATrHBuyAqijH8hoxmAGKQi9t-GGiyaFDEH8HjjhFpoLWgjiKuAiijAiDXCABz9Kl1OEyZ-VHy5DAByXLzoGiaBABGcxaKayGhaiUCqbzoCu7A8xm5AUyUqyUW3C8ho9EW5axSVV8jyEe-mi2Kq-dKaxiaxqbx2fglzokGczUsx64-2a3e4o8pE4icx-3fDwVwxyocE98cU8ohwlEjwxzU4K4EtwTwj9Unwo8-K3-2e4Euw08qq0dqg07Ka03iC0rq78K0-80oZwCxq4o22wipA0pO1Mw0JBc0118w3Xtw6IwtU6G1BCw0KzwCw1GS0tSqawBwHDLQ0mZ384XDOWUC0D81AE2mCwa20L832w3R4',

        '__comet_req': '15',

        'fb_dtsg': fb_dtsg,

        'jazoest': jazoest,

        'lsd': '2bA5j70hHausxyda70P9Hc',

        '__spin_r': '1007781546',

        '__spin_b': 'trunk',

        '__spin_t': '1688318891',

        'fb_api_caller_class': 'RelayModern',

        'fb_api_req_friendly_name': 'usePagesCometEditPageVisibilityMutation',

        'variables': json.dumps({

            'input': {

                'client_mutation_id': '4',

                'actor_id': idpro5,

                'page_id': uid_page,

                'publish_mode': 'PUBLISHED'

            }

        }),

    'server_timestamps': 'true',

    'doc_id': '4920939114687785'

    }

    #print(data)

    #print(headers)

    response = requests.post('https://www.facebook.com/api/graphql/', headers=headers, data=data).text

    #print(response)

    print('\033[1;31m[\033[0;93m'+str(x+1)+'\033[1;31m] | \033[1;36m'+str(time)+' \033[1;31m| \033[0;93mSUCCESS \033[1;31m| \033[1;35m'+str(uid_page)+' \033[1;31m| \033[1;34m'+str(name_page)+' \033[1;31m| \033[1;37m'+str(idpro5)+' ')

# =================[ START TOOL ]===========================

clear()

banner()

cookie = input(ndp_tool+luc+'Vui Lòng Nhập Cookie Facebook'+trang+': '+vang)

# Get fb_dtsg + jazoest

headers = {

        'authority': 'mbasic.facebook.com',

        'cache-control': 'max-age=0',

        'sec-ch-ua': '"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"',

        'sec-ch-ua-mobile': '?0',

        'sec-ch-ua-platform': '"Windows"',

        'upgrade-insecure-requests': '1',

        'origin': 'https://mbasic.facebook.com',

        'content-type': 'application/x-www-form-urlencoded',

        'user-agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',

        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',

        'sec-fetch-site': 'same-origin',

        'sec-fetch-mode': 'navigate',

        'sec-fetch-user': '?1',

        'sec-fetch-dest': 'document',

        'referer': 'https://mbasic.facebook.com/',

        'accept-language': 'en-US,en;q=0.9',

        'cookie': cookie,

}

try:

    print(ndp_tool+xnhac+"Đang Check Live Cookie...!", end="\r")

    get_token = requests.get('https://firet.io/firetx_retro/api/getthongtinck.php?cookie='+cookie).json()

    print(get_token)

    find_data = requests.get("https://mbasic.facebook.com/", headers=headers).text

    fb_dtsg = find_data.split('<input type="hidden" name="fb_dtsg" value="')[1].split('"')[0]

    jazoest = find_data.split('<input type="hidden" name="jazoest" value="')[1].split('"')[0]

    tokenpro5 = get_token['token']

    namepro5 = get_token["name"]

    idpro5 = get_token['id']

except:

    exit(ndp_tool+do+"Cookie Die Vui Lòng Kiểm Tra Lại!!")

url = "https://firet.io/firetx_retro/api/getpagean.php?cookie=" + cookie

getidpro5 = requests.get(url).json()

print(getidpro5)

list_id_name_page = []

for i in getidpro5:

    uid_page = i['id']

    name_page = i['name']

    so_luong = i['count']

    gomlist = f'{uid_page}|{name_page}'

    list_id_name_page.append(gomlist)

# NHẬP DELAY + SỐ LƯỢNG BUFF

clear()

banner()

print(ndp_tool+luc+'Get Thành Công: '+trang+str(len(list_id_name_page))+luc+' Page Pro5')

thanh()

soluongrungr = len(list_id_name_page)

thanh()

delay = int(input(ndp_tool+luc+'Nhập Delay'+trang+': '+vang))

thanh()

# RUN THAM GIA GROUP

for x in range(soluongrungr):

    threading.Thread(target=rungr,args=(x, )).start()

    ndp_delay(delay)


import numpy as np
from scipy.optimize import differential_evolution
import matplotlib.pyplot as plt

xData = [7, 7.25, 7.5, 7.75, 8, 8.25, 8.5]
yData = [8.24, 8.53, 8.87, 9.18, 9.48, 9.98, 10.32]
unc = [.05, .05, .06, .03, .01, .03, .03]

def LinearFit(x, y, u):
    """
    Fits a linear model by scipy.optimize.differential_evolution

    Parameters
    ----------
    x : (n) array_like
        1-dimensional list of x-values.
    y : (n), array_like
        1-dimensional list of y-values.
    u : (n) array_like
        1-dimensional list of uncertainties for y-values.
    Returns
    -------
    a, b : Optimal parameters for linear model a + bx
    red_chi_sq : float
        reduced chi squared as calculated by the sum of squared residuals
    """
    x = np.asarray(x)
    y = np.asarray(y)
    u = np.asarray(u)
    bounds = [[-1000, 1000]] + [[-1000, 1000]]

    def objective(s):
        a, b = np.split(s, 2)
        return np.sum(((y - b*x-a)**2.)/(u**2.))

    result = differential_evolution(objective, bounds)
    print(result)
    s = result['x']
    red_chi_sq = objective(s)/(len(x)-len(s))
    a, b = np.split(s, 2)
    return a, b, red_chi_sq

a, b, red_chi_sq = LinearFit(xData, yData, unc)
print(a)
print(b)
print(red_chi_sq)

#plot of fit vs data
fig = plt.figure()
plt.errorbar(xData, yData, yerr=unc, fmt='ro')
plt.plot(xData, a+b*xData, 'b', label = '1.41x-1.75')
plt.title('Angular Frequency vs Voltage')
plt.xlabel('Voltage (V)')
plt.ylabel('Angular Frequency (rad/sec)')
plt.legend()
plt.savefig('freq.png', dpi=300, bbox_inches='tight')
plt.close()

height = [3.1, 4.8, 4.1, 3.5, 2.4]
upper = [9.55, 9.97, 9.74, 9.64, 9.33]
lower = [8.36, 8.27, 8.30, 8.32, 8.42]
upunc = [.34, .35, .35, .34, .34]
lowunc = [.32, .32, .32, .32, .32]

aUp, bUp, red_chi_sqUp = LinearFit(height, upper, upunc)
print(aUp)
print(bUp)
print(red_chi_sqUp)

aLow, bLow, red_chi_sqLow = LinearFit(height, lower, lowunc)
print(aLow)
print(bLow)
print(red_chi_sqLow)

#plot of best fit vs data
fig = plt.figure()
plt.errorbar(height, upper, yerr=upunc, fmt='ro')
plt.errorbar(height, lower, yerr=lowunc, fmt='bo')
plt.plot(height, aUp+bUp*height, 'r', label = 'Upper Bound Fit: .255x+8.73')
plt.plot(height, aLow+bLow*height, 'b', label = 'Lower Bound Fit: -.0616x+8.55')
plt.title('Upper and Lower Bounds on Unstable Region')
plt.xlabel('Height Modulation Amplitude (cm)')
plt.ylabel('Angular Frequency (rad/sec)')
plt.legend()
plt.savefig('bounds.png', dpi=300, bbox_inches='tight')
plt.close()

xx = np.linspace(2.4, 4.8, num=50)
theoryUp = []
theoryLow = []
for i in xx:
    theoryUp.append(0.193*i+9.12)
    theoryLow.append((-0.193)*i+9.12)

#plot of theoretical fit vs data
fig = plt.figure()
plt.errorbar(height, upper, yerr=upunc, fmt='ro')
plt.errorbar(height, lower, yerr=lowunc, fmt='bo')
plt.plot(xx, theoryUp, 'r', label = 'Theoretical Upper Bound: .193x+9.12')
plt.plot(xx, theoryLow, 'b', label = 'Theoretical Lower Bound: -.193x+9.12')
plt.title('Theoretical Upper and Lower Bounds on Unstable Region')
plt.xlabel('Height Modulation Amplitude (cm)')
plt.ylabel('Angular Frequency (rad/sec)')
plt.legend()
plt.savefig('theory.png', dpi=300, bbox_inches='tight')
plt.close()

theoryUpPt = [9.72, 10.05, 9.91, 9.79, 9.58]
theoryLowPt = [8.52, 8.19, 8.33, 8.44, 8.65]
UpResid = np.subtract(upper, theoryUpPt)
LowResid = np.subtract(lower, theoryLowPt)

#Upper theoretical residual
fig = plt.figure()
plt.errorbar(height, UpResid, yerr=upunc, fmt='ro')
plt.title('Residual Plot of Theoretical Upper Bounds')
plt.xlabel('Height Modulation Amplitude (cm)')
plt.ylabel('Angular Frequency (rad/sec)')
plt.savefig('upperresiduals.png', dpi=300, bbox_inches='tight')
plt.close()

#Lower theoretical residual
fig = plt.figure()
plt.errorbar(height, LowResid, yerr=lowunc, fmt='bo')
plt.title('Residual Plot of Theoretical Lower Bounds')
plt.xlabel('Height Modulation Amplitude (cm)')
plt.ylabel('Angular Frequency (rad/sec)')
plt.savefig('lowerresiduals.png', dpi=300, bbox_inches='tight')
plt.close()

logAngle = [2.3, 2.08, 1.79, 1.39, 0.69]
time = [0, 32.16, 74.06, 133.65, 220.74]
timeunc = [0.01, 0.83, 1.12, 3.20, 6.62]

aDamp, bDamp, red_chi_sqDamp = LinearFit(logAngle, time, timeunc)
print(aDamp)
print(bDamp)
print(red_chi_sqDamp)

#plot of fit vs data
fig = plt.figure()
plt.errorbar(logAngle, time, yerr=timeunc, fmt='ro')
plt.plot(logAngle, aDamp+bDamp*logAngle, 'b', label = '-144.55x + 332.46')
plt.title('Log of Amplitude vs Time for Damped Pendulum')
plt.ylabel('Time (s)')
plt.xlabel('Log of Angle (Degrees)')
plt.legend()
plt.savefig('damping.png', dpi=300, bbox_inches='tight')
plt.close()


from collections import OrderedDict
import heterocl as hcl
import heterocl.tvm as tvm
import numpy as np
import hlib
from ..utils import *
from .op import *

dtype = hcl.Float()

sum = hcl.reducer(0, lambda x, y: x + y, dtype)
max = hcl.reducer(-1, lambda x, y: tvm.make.Max(x, y), dtype)
_all = hcl.reducer(True, lambda x, y: x & y, bool)

def simplify(expr):
    return tvm.ir_pass.Simplify(expr) if isinstance(expr, tvm.expr.Expr) else expr

def pad(data, pad_before, pad_after=None, pad_value=0.0, name="pad"):
    n = len(data.shape)
    pad_after = pad_after if pad_after else pad_before
    if len(pad_before) != n:
        raise ValueError(
            "Input dimension and pad_before dismatch : %d vs %d" %
            (n, len(pad_before)))
    if len(pad_after) != n:
        raise ValueError(
            "Input dimension and pad_after dismatch : %d vs %d" %
            (n, len(pad_after)))
    out_shape = tuple(
        tvm.ir_pass.Simplify(
            (data.shape[i] + tvm.const(pad_before[i] + pad_after[i]))
        ) for i in range(n))
    pad_value = pad_value if isinstance(pad_value, tvm.expr.Expr) else tvm.const(pad_value, data.dtype)

    def _pad(*indices):
        not_zero = []
        index_tuple = []
        for i in range(n):
            if pad_before[i] == 0 and pad_after[i] == 0:
                index_tuple.append(indices[i])
            else:
                index_tuple.append(indices[i] - pad_before[i])
                not_zero.append(indices[i] >= pad_before[i])
                not_zero.append(indices[i] < data.shape[i] + pad_before[i])
        if not_zero:
            not_zero = tvm.all(*not_zero)
            return tvm.select(not_zero, data[tuple(index_tuple)], pad_value)
        return data[tuple(index_tuple)]

    return hcl.compute(out_shape, _pad, name=name)

def relay_pad(data, pad_width, pad_value=0.0,
              pad_mode='constant', frontend='keras'):
    pad_before = []
    pad_after = []
    for padded in pad_width:
        pad_before.append(tvm_to_primitive(padded[0]))
        pad_after.append(tvm_to_primitive(padded[1]))
    return pad(data, pad_before, pad_after, pad_value)

def get_pad_tuple(padding, kernel):
    if isinstance(padding, (tuple, list)):
        pad_h = padding[0] * 2
        pad_w = padding[1] * 2
    elif isinstance(padding, int):
        pad_h = pad_w = padding * 2
    elif padding == "VALID":
        pad_h = 0
        pad_w = 0
    elif padding == "SAME":
        pad_h = kernel[0] - 1
        pad_w = kernel[1] - 1
    else:
        raise ValueError("Unknown padding option %s" % padding)
    pad_top = ((pad_h + 1) // 2)
    pad_left = ((pad_w + 1) // 2)
    return pad_top, pad_left, pad_h - pad_top, pad_w - pad_left

def dilate(data, strides, name="DilatedInput"):
    n = len(data.shape)
    if len(strides) != n:
        raise ValueError(
            "data dimension and strides size dismatch : %d vs %d" %
            (n, len(strides)))

    out_shape = tuple(
        simplify((data.shape[i] - 1) * strides[i] + 1) for i in range(n))

    def _dilate(*indices):
        not_zero = []
        index_tuple = []
        for i in range(n):
            if strides[i] != 1:
                index_tuple.append(indices[i] / strides[i])
                not_zero.append((indices[i] % strides[i]).equal(0))
            else:
                index_tuple.append(indices[i])
        if not_zero:
            not_zero = tvm.api.all(*not_zero)
            if not_zero:
                return data(*index_tuple)
            else:
                return hcl.cast(data.dtype, 0.0)
        return data(*index_tuple)
    return hcl.compute(out_shape, _dilate, name=name)

def conv2d_transpose(
        data,
        kernel,
        strides=[1, 1],
        padding=[0, 0],
        out_dtype=None):
    if out_dtype is None:
        out_dtype = data.dtype
    """Implementation of conv2d transpose"""
    batch, in_c, in_h, in_w = data.shape
    _, out_c, filter_h, filter_w = kernel.shape
    stride_h, stride_w = strides
    # dilate stage
    DilatedInput = dilate(
        data, [1, 1, stride_h, stride_w], name='DilatedInput')
    # padding stage
    fpad_top, fpad_left, fpad_bottom, fpad_right = get_pad_tuple(
        padding, (filter_h, filter_w))
    bpad_top = filter_h - 1 - fpad_top
    bpad_bottom = filter_h - 1 - fpad_bottom
    bpad_left = filter_w - 1 - fpad_left
    bpad_right = filter_w - 1 - fpad_right
    PaddedInput = pad(DilatedInput,
                      [0, 0, bpad_top, bpad_left],
                      [0, 0, bpad_bottom, bpad_right],
                      name='PaddedInput')
    # convolution stage
    out_c = simplify(out_c)
    out_h = simplify((in_h - 1) * stride_h - fpad_top - fpad_bottom + filter_h)
    out_w = simplify((in_w - 1) * stride_w - fpad_left - fpad_right + filter_w)
    dc = hcl.reduce_axis((0, in_c), name='dc')
    dh = hcl.reduce_axis((0, filter_h), name='dh')
    dw = hcl.reduce_axis((0, filter_w), name='dw')

    return hcl.compute(
        (batch, out_c, out_h, out_w),
        lambda b, c, h, w: hcl.sum(
            PaddedInput[b, dc, h + dh, w + dw].astype(out_dtype) *
            kernel[dc, c, filter_h - 1 - dh,
                   filter_w - 1 - dw].astype(out_dtype),
            axis=[dc, dh, dw]), name="conv2d_transpose")

def conv2d(
        Input,
        Filter,
        Bias=None,
        strides=[1, 1],
        padding=[0, 0],
        dilation=[1, 1],
        groups=1,
        channels=1,
        kernel_size=[1, 1],
        data_layout='NCHW',
        kernel_layout='OIHW',
        out_layout='',
        name="conv2d",
        out_dtype=None,
        frontend='keras'):
    p = []
    s = []
    d = []
    for i in range(len(padding)):
        p.append(tvm_to_primitive(padding[i]))
    for i in range(len(strides)):
        s.append(tvm_to_primitive(strides[i]))
        d.append(tvm_to_primitive(dilation[i]))
    strides = s
    padding = p
    dilation = d
    channels = tvm_to_primitive(channels)
    groups = tvm_to_primitive(groups)
    if out_dtype is None or out_dtype == '':
        out_dtype = Input.dtype
    if data_layout == 'NCHW':
        out = conv2d_nchw(
            Input,
            Filter,
            strides,
            padding,
            dilation,
            name='conv2d',
            groups=groups,
            out_dtype=out_dtype)
    elif data_layout == 'NHWC':
        out = conv2d_nhwc(
            Input,
            Filter,
            strides,
            padding,
            dilation,
            name='conv2d',
            groups=groups,
            out_dtype=out_dtype)
    elif data_layout == 'HWCN':
        out = conv2d_hwcn(
            Input,
            Filter,
            strides,
            padding,
            dilation,
            name='conv2d',
            groups=groups,
            out_dtype=out_dtype)
    else:
        raise ValueError("not support this layout {} yet".format(data_layout))
    return out

def conv2d_nhwc(
        Input,
        Filter,
        strides=[1, 1],
        padding=[1, 1],
        dilation=[1, 1],
        out_dtype='float',
        groups=1,
        name='conv2d'):
    assert isinstance(strides, int) or len(strides) == 2
    assert isinstance(dilation, int) or len(dilation) == 2
    if out_dtype is None:
        out_dtype = Input.dtype
    if isinstance(strides, int):
        stride_h = stride_w = strides
    else:
        stride_h, stride_w = strides

    if isinstance(dilation, int):
        dilation_h = dilation_w = dilation
    else:
        dilation_h, dilation_w = dilation

    batch, in_height, in_width, in_channel = Input.shape
    kernel_h, kernel_w, channel, num_filter = Filter.shape

    dilated_kernel_h = (kernel_h - 1) * dilation_h + 1
    dilated_kernel_w = (kernel_w - 1) * dilation_w + 1
    pad_top, pad_left, pad_down, pad_right = get_pad_tuple(
        padding, (dilated_kernel_h, dilated_kernel_w))
    out_channel = num_filter
    out_height = simplify(
        (in_height -
         dilated_kernel_h +
         pad_top +
         pad_down) //
        stride_h +
        1)
    out_width = simplify(
        (in_width -
         dilated_kernel_w +
         pad_left +
         pad_right) //
        stride_w +
        1)
    pad_before = [0, pad_top, pad_left, 0]
    pad_after = [0, pad_down, pad_right, 0]
    temp = pad(Input, pad_before, pad_after, name="temp")
    rc = hcl.reduce_axis(0, in_channel, name='rc')
    ry = hcl.reduce_axis(0, kernel_h, name='ry')
    rx = hcl.reduce_axis(0, kernel_w, name='rx')
    return hcl.compute(
        (batch, out_height, out_width, out_channel),
        lambda nn, yy, xx, ff: hcl.sum(
            temp[nn, yy * stride_h + ry * dilation_h,
                 xx * stride_w + rx * dilation_w, rc] *
            Filter[ry, rx, rc, ff], axis=[ry, rx, rc],
            name=name, dtype=out_dtype))

def conv2d_nchw(
        Input,
        Filter,
        strides=[1, 1],
        padding=[0, 0],
        dilation=[1, 1],
        out_dtype=None,
        groups=1,
        name='conv2d'):
    if out_dtype is None or out_dtype == '':
        out_dtype = Input.dtype
    assert isinstance(strides, int) or len(strides) == 2
    assert isinstance(dilation, int) or len(dilation) == 2
    if isinstance(strides, int):
        stride_h = stride_w = strides
    else:
        stride_h, stride_w = strides

    if isinstance(dilation, int):
        dilation_h = dilation_w = dilation
    else:
        dilation_h, dilation_w = dilation

    if groups > 1:
        shape = Filter.shape
        new_shape = (shape[0], groups, shape[2], shape[3])
        Filter = hcl.compute(new_shape, lambda o, i, h, w: Filter[o, 0, h, w])
    batch, in_channel, in_height, in_width = Input.shape
    num_filter, channel, kernel_h, kernel_w = Filter.shape
    # compute the output shape
    dilated_kernel_h = (kernel_h - 1) * dilation_h + 1
    dilated_kernel_w = (kernel_w - 1) * dilation_w + 1
    pad_top, pad_left, pad_down, pad_right = get_pad_tuple(
        padding, (dilated_kernel_h, dilated_kernel_w))
    out_channel = num_filter
    out_height = simplify(
        (in_height -
         dilated_kernel_h +
         pad_top +
         pad_down) //
        stride_h +
        1)
    out_width = simplify(
        (in_width -
         dilated_kernel_w +
         pad_left +
         pad_right) //
        stride_w +
        1)
    # compute graph
    pad_before = [0, 0, pad_top, pad_left]
    pad_after = [0, 0, pad_down, pad_right]
    temp = pad(Input, pad_before, pad_after, name="pad_temp")
    if groups > 1:
        rc = hcl.reduce_axis(0, channel / groups, name='rc')
    else:
        rc = hcl.reduce_axis(0, channel, name='rc')
    ry = hcl.reduce_axis(0, kernel_h, name='ry')
    rx = hcl.reduce_axis(0, kernel_w, name='rx')
    if groups > 1:
        return hcl.compute(
            (batch, out_channel, out_height, out_width),
            lambda nn, ff, yy, xx: hcl.sum(
                temp[nn, ff % groups, yy * stride_h + ry * dilation_h,
                     xx * stride_w + rx * dilation_w] *
                Filter[ff, rc, ry, rx],
                axis=[rc, ry, rx], dtype=out_dtype), name=name, dtype=out_dtype)
    return hcl.compute(
        (batch, out_channel, out_height, out_width),
        lambda nn, ff, yy, xx: hcl.sum(
            temp[nn, rc, yy * stride_h + ry * dilation_h,
                 xx * stride_w + rx * dilation_w] *
            Filter[ff, rc, ry, rx],
            axis=[rc, ry, rx], dtype=out_dtype), name=name, dtype=out_dtype)

def conv2d_hwcn(
        Input,
        Filter,
        strides=[1, 1],
        padding=[0, 0],
        dilation=[1, 1],
        out_dtype=None,
        groups=1,
        name='conv2d'):
    if out_dtype is None:
        out_dtype = Input.dtype
    assert isinstance(strides, int) or len(strides) == 2
    assert isinstance(dilation, int) or len(dilation) == 2

    if isinstance(strides, int):
        stride_h = stride_w = strides
    else:
        stride_h, stride_w = strides

    if isinstance(dilation, int):
        dilation_h = dilation_w = dilation
    else:
        dilation_h, dilation_w = dilation

    in_height, in_width, in_channel, batch = Input.shape
    kernel_h, kernel_w, channel, num_filter = Filter.shape
    # compute the output shape
    dilated_kernel_h = (kernel_h - 1) * dilation_h + 1
    dilated_kernel_w = (kernel_w - 1) * dilation_w + 1
    pad_top, pad_left, pad_down, pad_right = get_pad_tuple(
        padding, (dilated_kernel_h, dilated_kernel_w))
    out_channel = num_filter
    out_height = simplify(
        (in_height -
         dilated_kernel_h +
         pad_top +
         pad_down) //
        stride_h +
        1)
    out_width = simplify(
        (in_width -
         dilated_kernel_w +
         pad_left +
         pad_right) //
        stride_w +
        1)
    pad_before = [pad_top, pad_left, 0, 0]
    pad_after = [pad_down, pad_right, 0, 0]
    temp = pad(Input, pad_before, pad_after, name="temp")
    rc = hcl.reduce_axis(0, in_channel, name='rc')
    ry = hcl.reduce_axis(0, kernel_h, name='ry')
    rx = hcl.reduce_axis(0, kernel_w, name='rx')
    return tvm.compute(
        (out_height, out_width, out_channel, batch),
        lambda yy, xx, ff, nn: hcl.sum(
            temp[yy * stride_h + ry * dilation_h, xx * stride_w + rx * dilation_w,
                 rc, nn] * Filter[ry, rx, rc, ff], axis=[ry, rx, rc],
            dtype=out_dtype),
        name=name)

def conv2d_nchw_old(
        Input,
        Filter,
        name="conv2d",
        stride=[1, 1],
        padding=[[0, 0], [0, 0]]):
    out_dtype = Input.dtype
    batch, in_channel, in_height, in_width = Input.shape
    num_filter, channel, kernel_h, kernel_w = Filter.shape
    stride_h, stride_w = stride
    [pad_top, pad_left], [pad_down, pad_right] = padding
    # compute the output shape
    out_channel = num_filter
    out_height = simplify(
        (in_height -
         kernel_h +
         pad_top +
         pad_down) //
        stride_h +
        1)
    out_width = simplify(
        (in_width -
         kernel_w +
         pad_left +
         pad_right) //
        stride_w +
        1)
    # compute graph
    pad_before = [0, 0, pad_top, pad_left]
    pad_after = [0, 0, pad_down, pad_right]
    if padding != [[0, 0], [0, 0]]:
        Input = pad(Input, pad_before, pad_after)
    rc = hcl.reduce_axis(0, in_channel)
    ry = hcl.reduce_axis(0, kernel_h)
    rx = hcl.reduce_axis(0, kernel_w)
    return hcl.compute(
        (batch, out_channel, out_height, out_width),
        lambda nn, ff, yy, xx: sum(
            Input[nn, rc, yy * stride_h + ry, xx * stride_w + rx] *
            Filter[ff, rc, ry, rx],
            axis=[rc, ry, rx]),
        name=name,
        attrs=OrderedDict([
            ('p', kernel_h),
            ('q', kernel_w),
            ('in_num', in_channel),
            ('out_num', out_channel),
            ('out_img_w', out_width),
            ('out_img_h', out_height),
            ('cin_dtype', tvm.make.StringImm(Input.dtype)),
            ('filter_dtype', tvm.make.StringImm(Filter.dtype)),
            ('app_name', tvm.make.StringImm('cnn'))]))

def dense(data, weight, units=None, out_dtype='', bias=None, name="dense"):
    assert len(
        data.shape) == 2 and len(
        weight.shape) == 2, "only support 2-dim dense"
    if bias is not None:
        assert len(bias.shape) == 1
    batch, in_dim = data.shape
    out_dim, _ = weight.shape
    k = hcl.reduce_axis(0, in_dim)
    attrs = OrderedDict([
        ('k', in_dim),
        ('j', out_dim),
        ('i', batch),
        ('app_name', tvm.make.StringImm('mm'))])
    matmul = hcl.compute((batch, out_dim), lambda i, j: sum(
        data[i, k] * weight[j, k], axis=k), name, attrs=attrs)
    if bias is not None:
        matmul = hcl.compute(
            (batch, out_dim),
            lambda i, j: matmul[i, j] + bias[j],
            name=name,
            attrs=attrs)
    return matmul

def bias_add(data, bias, axis=-1, name='bias_add'):
    def _broadcast(shape, *indices):
        axes = []
        indices = indices[0]
        for i in range(len(shape)):
            if shape[i] == 1:
                axes.append(0)
            else:
                axes.append(indices[i])
        return tuple(axes)
    data_len = len(data.shape)
    if axis < 0:
        axis += data_len
    num_newaxis = data_len - axis - 1
    bias = expand_dims(bias, len(bias.shape), num_newaxis)
    bias = expand_dims(bias, 0, axis)
    return hcl.compute(
        data.shape, lambda *x: data[x] + bias[_broadcast(bias.shape, x)], name=name)

def squeeze(data, axis=None, name='squeeze'):
    if axis is None:
        axis = []
        for i in range(len(data.shape)):
            if data.shape[i] == 1:
                axis.append(i)
    else:
        axis = [tvm_to_primitive(x) for x in axis]
    l_orig = len(data.shape)
    new_shape = []
    for i in range(len(data.shape)):
        if not i in axis:
            new_shape.append(data.shape[i])

    def _ind(axis, l_orig, *indices):
        indices = indices[0]
        new_shape = []
        idx = 0
        for i in range(l_orig):
            if i not in axis:
                new_shape.append(indices[idx])
                idx = idx + 1
            else:
                new_shape.append(0)
        return tuple(new_shape)
    return hcl.compute(
        tuple(new_shape), lambda *x: data[_ind(axis, l_orig, x)], name=name)

def split(data, indices_or_sections, axis=0, name='split'):
    def split_idx(start, axis, *indices):
        indices = indices[0]
        new_ind = []
        for i in range(len(indices)):
            if i == axis:
                new_ind.append(start + indices[i])
            else:
                new_ind.append(indices[i])
        return tuple(new_ind)
    try:
        if not hasattr(indices_or_sections, "value"):
            _list = []
            for section in indices_or_sections:
                _list.append(tvm_to_primitive(section))
            indices_or_sections = _list
    except BaseException:
        _list = []
        if isinstance(indices_or_sections, int):
            pass
        else:
            for section in indices_or_sections:
                _list.append(tvm_to_primitive(section))
            indices_or_sections = _list
    if not isinstance(indices_or_sections, list):
        if hasattr(indices_or_sections, "value"):
            indices_or_sections = indices_or_sections.value
        assert (axis >= 0 & axis < len(data.shape)
                ), "axis not in bounds of shape"
        assert(
            data.shape[axis] %
            indices_or_sections == 0), "indices doesn't divide equally"
        new_shape = list(data.shape)
        intval = new_shape[axis] // indices_or_sections
        new_shape[axis] = intval
        out = []
        for i in range(indices_or_sections):
            out.append(hcl.compute(
                tuple(new_shape), lambda *x: data[split_idx(i * intval, axis, x)], name=name))
    else:
        new_shape = []
        for s in range(len(indices_or_sections)):
            if hasattr(indices_or_sections[s], "value"):
                indices_or_sections[s] = indices_or_sections[s].value
        for i in range(len(indices_or_sections) + 1):
            new_shape.append(list(data.shape))
        start = 0
        axis_width = []
        for i in range(len(indices_or_sections)):
            ax = indices_or_sections[i]
            new_shape[i][axis] = ax - start
            axis_width.append(start)
            start = ax
        ax = new_shape[-1][axis]
        new_shape[-1][axis] = ax - start
        axis_width.append(start)
        out = []
        for i in range(len(indices_or_sections) + 1):
            out.append(hcl.compute(tuple(
                new_shape[i]), lambda *x: data[split_idx(axis_width[i], axis, x)], name=name))
    return tuple(out)

def concatenate(*data_tup, axis=1, name='concatenate', frontend='keras'):
    idx_start = [0]
    axis_len = 0
    for i in range(len(data_tup)):
        idx_start.append(idx_start[i] + (data_tup[i]).shape[axis])
        axis_len = axis_len + (data_tup[i]).shape[axis]

    new_shape = list(data_tup[0].shape)
    new_shape[axis] = axis_len
    C = hcl.placeholder(tuple(new_shape))

    def concat(data, offset, *indices):
        orig_idx = list(indices[0])
        idx = list(indices[0])
        idx[axis] = idx[axis] + offset
        orig_idx = tuple(orig_idx)
        idx = tuple(idx)
        C[idx] = data[orig_idx]
    for i in range(len(data_tup)):
        hcl.mutate(data_tup[i].shape,
                   lambda *x: concat(data_tup[i], idx_start[i], x),
                   name=name)
    return C

def reduce_mult(l):
    result = 1
    for item in l:
        result = result * item
    return result

def reshape(data, newshape, name='reshape'):
    new_shape = []
    for i in range(len(newshape)):
        new_shape.append(tvm_to_primitive(newshape[i]))
    res_shape = []
    cur_shape = list(data.shape)
    idx = 0
    idx_n1 = -1
    for _ in range(len(new_shape)):
        new_idx = new_shape[idx]
        assert(new_idx > -5), "idx has to be greater than -5"
        if new_idx > 0:
            res_shape.append(new_idx)
        elif new_idx == 0:
            res_shape.append(cur_shape[idx])
        elif new_idx == -1:
            if not idx_n1 == -1:
                raise ValueError("no more than one -1 is allowed in newshape")
            idx_n1 = idx
        elif new_idx == -2:
            res_shape.extend(cur_shape[idx:])
        elif new_idx == -3:
            res_shape.append(cur_shape[idx] + cur_shape[idx + 1])
            idx = idx + 1
        elif new_idx == -4:
            assert False, "not implemented yet"
        idx = idx + 1
    if not idx_n1 == -1:
        res_shape.insert(idx_n1, reduce_mult(cur_shape) // reduce_mult(res_shape))
    assert(reduce_mult(cur_shape) == reduce_mult(res_shape)), "shape must contain same total product"
    cur_order = [1]
    res_order = [1]
    c_ord = len(cur_shape) - 1
    for i in range(len(cur_shape) - 1):
        cur_order.append(cur_shape[c_ord - i] * cur_order[i])
    r_ord = len(res_shape) - 1
    for i in range(len(res_shape) - 1):
        res_order.append(res_shape[r_ord - i] * res_order[i])

    def _reshape_idx(*indices):
        indices = indices[0]
        elm_idx = 0
        data_idx = []
        for i in range(len(indices)):
            elm_idx = indices[r_ord - i] * res_order[i] + elm_idx
        for i in range(len(cur_order)):
            data_idx.append((elm_idx // (cur_order[c_ord - i])) % cur_shape[i])
        return tuple(data_idx)
    return hcl.compute(
        tuple(res_shape), lambda *x: data[_reshape_idx(x)], name=name)

def batch_norm(
        data,
        gamma,
        beta,
        moving_mean,
        moving_var,
        axis=1,
        epsilon=10**-7,
        center=1,
        scale=1,
        name="batch_norm"):
    if axis < 0:
        axis = len(data.shape) - 1
    mred = []
    vred = []
    size = 1.0
    for i in range(len(data.shape)):
        if not i == axis:
            mred.append(hcl.reduce_axis(0, data.shape[i], "mred" + str(i)))
            vred.append(hcl.reduce_axis(0, data.shape[i], "vred" + str(i)))
            size = size * data.shape[i]
    new_shape = (data.shape[axis],)

    def insert_axis(axis, red, *indices):
        idx = []
        cur_red = 0
        for i in range(len(data.shape)):
            if i == axis:
                idx.append(indices[0])
            else:
                idx.append(red[cur_red])
                cur_red = cur_red + 1
        return tuple(idx)

    def get_axis(axis, *indices):
        indices = list(indices[0])
        return (indices[axis],)
    out = hcl.compute(data.shape, lambda *x: (data[x] - moving_mean[get_axis(axis, x)]) /
                    (hcl.sqrt(moving_var[get_axis(axis, x)] + epsilon)) * gamma[get_axis(axis, x)]
                    + beta[get_axis(axis, x)], name=name, dtype=data.dtype)
    return out, moving_mean, moving_var

def batch_matmul(x, y, name="batch_matmul"):
    out_shape = (x.shape[0], x.shape[1], y.shape[2])
    k = hcl.reduce_axis(0, x.shape[2], "k")
    return hcl.compute(out_shape, lambda b, m, n: hcl.sum(x[b,m,k] * y[b,n,k], axis = [k]), name=name, dtype = x.dtype)

def dropout(data, rate=0.5):
    data = hcl.compute(data.shape, lambda *x: data[x])
    mask = hcl.compute(data.shape, lambda *x: hcl.cast(dtype, 1))
    return data, mask

def max_pool(data, kernel, stride, padding=[[0, 0], [0, 0]], name="max_pool2d"):
    assert len(data.shape) == 4, "only support 4-dim pooling"
    assert len(stride) == 2, "only support 2-dim stride"
    kernel_height, kernel_width = kernel
    stride_height, stride_width = stride
    batch, channel, height, width = data.shape
    [pad_top, pad_left], [pad_down, pad_right] = padding
    pad_before = [0, 0, pad_top, pad_left]
    pad_after = [0, 0, pad_down, pad_right]
    if padding != [[0, 0], [0, 0]]:
        data = pad(data, pad_before, pad_after, pad_value=tvm.min_value(data.dtype))
    out_height = simplify(
        (height -
         kernel_height +
         pad_top +
         pad_down) //
        stride_height +
        1)
    out_width = simplify(
        (width -
         kernel_width +
         pad_left +
         pad_right) //
        stride_width +
        1)
    dheight = hcl.reduce_axis(0, kernel_height)
    dwidth = hcl.reduce_axis(0, kernel_width)

    return hcl.compute(
        (batch, channel, out_height, out_width),
        lambda i, c, h, w: max(data[i, c, h *
                                    stride_height +
                                    dheight, w *
                                    stride_width +
                                    dwidth], axis=[dheight, dwidth]),
        name=name,
        attrs=OrderedDict([
            ('out_img_w', out_width),
            ('out_img_h', out_height),
            ('in_num', channel),
            ('kernel_h', kernel[1]),
            ('kernel_w', kernel[0]),
            ('stride_h', stride[1]),
            ('stride_w', stride[0]),
            ('app_name', tvm.make.StringImm('max_pool'))]))

def max_pool2d(
        data,
        pool_size=[1, 1],
        strides=[1, 1],
        padding=[0, 0],
        layout='NCHW',
        name='max_pool2d'):
    pooling = []
    stride = []
    pad = []
    for i in range(len(pool_size)):
        pooling.append(tvm_to_primitive(pool_size[i]))
        stride.append(tvm_to_primitive(strides[i]))
    for i in range(len(padding)):
        pad.append(tvm_to_primitive(padding[i]))
    if layout == 'NCHW':
        out = max_pool2d_nchw(data, pooling, stride, pad, name)
    elif layout == 'NHWC':
        out = max_pool2d_nhwc(data, pooling, stride, pad, name)
    else:
        raise ValueError("not support this layout {} yet".format(layout))
    return out

def max_pool2d_nchw(data, pooling, stride, padding, name='max_pool2d'):
    assert len(data.shape) == 4, "only support 4-dim pooling"
    assert len(stride) == 2, "only support 2-dim stride"
    max = hcl.reducer(
        tvm.min_value(data.dtype),
        lambda x, y: tvm.make.Max(x, y),
        data.dtype)
    pooling_h, pooling_w = pooling
    stride_h, stride_w = stride
    batch, channel, height, width = data.shape
    if len(padding) == 4:
        pad_top = padding[0]
        pad_left = padding[1]
        pad_bottom = padding[2]
        pad_right = padding[3]
    else:
        pad_top, pad_left, pad_bottom, pad_right = get_pad_tuple(padding, (pooling_h, pooling_w))
    pad_before = [0, 0, pad_top, pad_left]
    pad_after = [0, 0, pad_bottom, pad_right]
    data = pad(data, pad_before, pad_after, pad_value=tvm.min_value(data.dtype))
    out_height = simplify(
        (height - pooling_h + pad_top + pad_bottom) // stride_h + 1)
    out_width = simplify(
        (width - pooling_w + pad_left + pad_right) // stride_w + 1)
    dheight = hcl.reduce_axis(0, pooling_h)
    dwidth = hcl.reduce_axis(0, pooling_w)
    return hcl.compute(
        (batch, channel, out_height, out_width),
        lambda i, c, h, w: max(data[i, c, h *
                                    stride_h +
                                    dheight, w *
                                    stride_w +
                                    dwidth], axis=[dheight, dwidth]),
        name=name, dtype=data.dtype,
        attrs=OrderedDict([
            ('out_img_w', out_width),
            ('out_img_h', out_height),
            ('in_num', channel),
            ('kernel_h', pooling[1]),
            ('kernel_w', pooling[0]),
            ('stride_h', stride[1]),
            ('stride_w', stride[0]),
            ('app_name', tvm.make.StringImm('max_pool'))]))

def max_pool2d_nhwc(
        data,
        pooling,
        stride=[1, 1],
        padding=[0, 0],
        name='max_pool2d'):
    assert len(data.shape) == 4, "only support 4-dim pooling"
    assert len(stride) == 2, "only support 2-dim stride"
    max = hcl.reducer(
        tvm.min_value(
            data.dtype), lambda x, y: tvm.make.Max(
            x, y), data.dtype)
    pooling_h, pooling_w = pooling
    stride_h, stride_w = stride
    batch, height, width, channel = data.shape
    if len(padding) == 4:
        pad_top = padding[0]
        pad_left = padding[1]
        pad_bottom = padding[2]
        pad_right = padding[3]
    else:
        pad_top, pad_left, pad_bottom, pad_right = get_pad_tuple(padding, (pooling_h, pooling_w))
    pad_before = [0, pad_top, pad_left, 0]
    pad_after = [0, pad_bottom, pad_right, 0]
    data = pad(
        data,
        pad_before,
        pad_after,
        pad_value=tvm.min_value(
            data.dtype))
    out_height = simplify(
        (height - pooling_h + pad_top + pad_bottom) // stride_h + 1)
    out_width = simplify(
        (width - pooling_w + pad_left + pad_right) // stride_w + 1)
    dheight = hcl.reduce_axis(0, pooling_h)
    dwidth = hcl.reduce_axis(0, pooling_w)
    return hcl.compute(
        (batch, out_height, out_width, channel),
        lambda i, h, w, c: max(data[i, h *
                                    stride_h +
                                    dheight, w *
                                    stride_w +
                                    dwidth, c], axis=[dheight, dwidth]),
        name=name,
        attrs=OrderedDict([
            ('out_img_w', out_width),
            ('out_img_h', out_height),
            ('in_num', channel),
            ('kernel_h', pooling[1]),
            ('kernel_w', pooling[0]),
            ('stride_h', stride[1]),
            ('stride_w', stride[0]),
            ('app_name', tvm.make.StringImm('max_pool'))]))

def avg_pool2d(
        data,
        pool_size=[1, 1],
        strides=[1, 1],
        padding=[0, 0],
        layout='NCHW',
        name='avg_pool2d'):
    pooling = []
    stride = []
    pad = []
    for i in range(len(pool_size)):
        pooling.append(tvm_to_primitive(pool_size[i]))
        stride.append(tvm_to_primitive(strides[i]))
        pad.append(tvm_to_primitive(padding[i]))
    if layout == 'NCHW':
        out = avg_pool2d_nchw(data, pooling, stride, pad, name)
    elif layout == 'NHWC':
        out = avg_pool2d_nhwc(data, pooling, stride, pad, name)
    else:
        raise ValueError("not support this layout {} yet".format(layout))
    return out

def avg_pool2d_nchw(data, pooling, stride, padding, name='avg_pool2d'):
    assert len(data.shape) == 4, "only support 4-dim pooling"
    assert len(stride) == 2, "only support 2-dim stride"
    pooling_h, pooling_w = pooling
    stride_h, stride_w = stride
    batch, channel, height, width = data.shape
    if len(padding) == 4:
        pad_top, pad_left, pad_bottom, pad_right = padding
    else:
        pad_top, pad_left, pad_bottom, pad_right = get_pad_tuple(
            padding, (pooling_h, pooling_w))
    pad_before = [0, 0, pad_top, pad_left]
    pad_after = [0, 0, pad_bottom, pad_right]
    data = pad(
        data,
        pad_before,
        pad_after,
        pad_value=tvm.const(
            0.0,
            data.dtype))
    out_height = simplify(
        (height - pooling_h + pad_top + pad_bottom) // stride_h + 1)
    out_width = simplify(
        (width - pooling_w + pad_left + pad_right) // stride_w + 1)
    dheight = hcl.reduce_axis(0, pooling_h)
    dwidth = hcl.reduce_axis(0, pooling_w)
    return hcl.compute(
        (batch, channel, out_height, out_width),
        lambda i, c, h, w: (sum(data[i, c, h *
                                     stride_h +
                                     dheight, w *
                                     stride_w +
                                     dwidth], axis=[dheight, dwidth]) /
                            (pooling_w *
                             pooling_h)),
        name=name,
        attrs=OrderedDict([
            ('out_img_w', out_width),
            ('out_img_h', out_height),
            ('in_num', channel),
            ('kernel_h', pooling[1]),
            ('kernel_w', pooling[0]),
            ('stride_h', stride[1]),
            ('stride_w', stride[0]),
            ('app_name', tvm.make.StringImm('avg_pool'))]))

def avg_pool2d_nhwc(
    data, pooling, stride=[
        1, 1], padding=[
            0, 0], name='avg_pool2d'):
    assert len(data.shape) == 4, "only support 4-dim pooling"
    assert len(stride) == 2, "only support 2-dim stride"
    pooling_h, pooling_w = pooling
    stride_h, stride_w = stride
    batch, height, width, channel = data.shape
    pad_top, pad_left, pad_bottom, pad_right = get_pad_tuple(
        padding, (pooling_h, pooling_w))
    pad_before = [0, pad_top, pad_left, 0]
    pad_after = [0, pad_bottom, pad_right, 0]
    data = pad(
        data,
        pad_before,
        pad_after,
        pad_value=tvm.const(
            0.0,
            data.dtype))
    out_height = simplify(
        (height - pooling_h + pad_top + pad_bottom) // stride_h + 1)
    out_width = simplify(
        (width - pooling_w + pad_left + pad_right) // stride_w + 1)
    dheight = hcl.reduce_axis(0, pooling_h)
    dwidth = hcl.reduce_axis(0, pooling_w)
    return hcl.compute(
        (batch, out_height, out_width, channel),
        lambda i, h, w, c: sum(data[i, h * stride_h + dheight, w * stride_w +
            dwidth, c], axis=[dheight, dwidth]) / (pooling_w * pooling_h),
            name=name,
            attrs=OrderedDict([
                ('out_img_w', out_width),
                ('out_img_h', out_height),
                ('in_num', channel),
                ('kernel_h', pooling[1]),
                ('kernel_w', pooling[0]),
                ('stride_h', stride[1]),
                ('stride_w', stride[0]),
                ('app_name', tvm.make.StringImm('avg_pool'))]))

def global_max_pool2d(data, layout='NCHW', name='global_max_pool2d'):
    stride = [1, 1]
    padding = [0, 0]
    if layout == 'NCHW':
        pooling = [data.shape[2], data.shape[3]]
        return max_pool2d_nchw(data, pooling, stride, padding, name)
    if layout == 'NHWC':
        pooling = [data.shape[1], data.shape[2]]
        return max_pool2d_nhwc(data, pooling, stride, padding, name)
    raise ValueError("not support this layout {} yet".format(layout))

def global_avg_pool2d(data, layout='NCHW', name='global_avg_pool2d'):
    stride = [1, 1]
    padding = [0, 0]
    if layout == 'NCHW':
        pooling = [data.shape[2], data.shape[3]]
        return avg_pool2d_nchw(data, pooling, stride, padding, name)
    if layout == 'NHWC':
        pooling = [data.shape[1], data.shape[2]]
        return avg_pool2d_nhwc(data, pooling, stride, padding, name)
    raise ValueError("not support this layout {} yet".format(layout))

def transpose(data, axes=[], name="transpose"):
    new_shape = []
    if len(axes) == 0:
        for i in range(len(data.shape)):
            axes.append(i)
    for i in range(len(axes)):
        new_axis = tvm_to_primitive(axes[i])
        if tvm_to_primitive(axes[i]) < 0:
            new_axis = len(data.shape) + tvm_to_primitive(axes[i])
            axes[i] = new_axis
        assert (
            new_axis >= 0 and new_axis < len(
                data.shape)), "axis={} is invalid for the {}-dimensional input tensor".format(
            new_axis, len(
                data.shape))
        for j in range(len(axes)):
            if (not i == j):
                assert(not new_axis == axes[j]), "repeated axis in transpose"
        new_shape.append(data.shape[new_axis])
    new_shape = tuple(new_shape)

    def _transpose(*indices):
        if len(axes) != 0:
            idx = [1] * len(axes)
            for i in range(len(axes)):
                idx[tvm_to_primitive(axes[i])] = indices[0][i]
        else:
            idx = indices[0]
        return idx
    return hcl.compute(new_shape, lambda *x: data[tuple(_transpose(x))], name=name,
        attrs=OrderedDict([('app_name',tvm.make.StringImm('transpose'))]))

def flatten(data, name="flatten"):
    ishape = data.shape
    dim = 1
    for i in range(1, len(ishape)):
        dim = dim * ishape[i]
    oshape = (ishape[0], dim)

    def unwrap(idx, shape):
        index = []
        for s in reversed(shape):
            index.append(idx % s)
            idx = idx / s
        return list(reversed(index))

    return hcl.compute(oshape, lambda i,j: data[tuple([i] + unwrap(j,ishape[1:]))],
        name=name,attrs=OrderedDict([('app_name',tvm.make.StringImm('flatten'))]))

def softmax(x, name="softmax", axis=0, frontend='keras'):
    shape = x.shape
    k = hcl.reduce_axis(0, shape[axis])
    new_shape = []
    for i in range(len(shape)):
        if i != axis:
            new_shape.append(shape[i])

    def _reduce_axis(axis, new_axis, keep_axis, *indices):
        indices = indices[0]
        new_ind = []
        put_axis = False
        for i in range(len(indices)):
            if i == axis and keep_axis:
                new_ind.append(new_axis)
                put_axis = True
                new_ind.append(indices[i])
            elif i != axis:
                new_ind.append(indices[i])
        if put_axis == False and keep_axis:
            new_ind.append(new_axis)
        return tuple(new_ind)
    max_elem = hcl.compute(
        tuple(new_shape), lambda *y: max(x[_reduce_axis(axis, k, True, y)], axis=[k]))
    k = hcl.reduce_axis(0, shape[axis])
    expsum = hcl.compute(
        tuple(new_shape), lambda *y: sum(tvm.exp(x[_reduce_axis(axis, k, True, y)] - max_elem[y]), axis=k))
    return hcl.compute(
        x.shape, lambda *y: tvm.exp(x[y] - max_elem[_reduce_axis(axis, k, False, y)]) / expsum[_reduce_axis(axis, k, False, y)], name)

def relu(data, name='relu'):
    return hcl.compute(data.shape,lambda *y: hcl.select(
        data[y] < 0, hcl.cast(data.dtype, 0), data[y]), name)

def leakyrelu(data, alpha=0.01):
    return hcl.compute(
        data.shape, lambda *y: hcl.select(data[y] < 0, alpha * data[y], data[y]))

def prelu(data, alpha, axis=1):
    def _axis_ind(axis, ind):
        ind = ind[0]
        new_ind = []
        for i in range(len(ind)):
            if i == axis:
                new_ind = ind[i]
        return tuple(new_ind)
    return hcl.compute(data.shape,lambda *x: hcl.select(
        data[x] < 0,
        hcl.cast(data.dtype, alpha[_axis_ind(axis,x)] * data[x]),
        data[x]))

def elu(data, alpha):
    return hcl.compute(data.shape,lambda *x: hcl.select(
        data[x] < 0, alpha * (hcl.exp(data[x])-1), data[x]))

def thresholdedrelu(data, theta):
    return hcl.compute(data.shape,lambda *x: hcl.select(
        data[x] > theta, data[x], hcl.cast(data.dtype, 0)))


# wcsremap by Andrew Becker script

# wcsremap -template template.fits -source input.fits -outIm input_remapped.fits
# usage : python wcsremap.py 'Calibrated*.fits' ref.fits
# Changsu Choi 2017/6/28
# multi processing perfomance is not good as expected, so use single cpu run 'for' script part

import glob
import os,sys
from multiprocessing import Process, Pool
import astropy.io.fits as fits
import numpy as np
import alipy
import glob

refim='ref.fits'

def identify_transform(ref_image, images_to_align,rad= 5, nb=500,verbose=False, visual=False):
    identifications = alipy.ident.run(ref_image, images_to_align,r=rad, n=nb, visu=visual)
    if verbose:
        for id in identifications:  # list of the same length as images_to_align.
            if id.ok is True:  # i.e., if it worked
                print("%20s : %20s, flux ratio %.2f" % (id.ukn.name,
                                                        id.trans,
                                                        id.medfluxratio))

            else:
                print( "%20s : no transformation found !" % (id.ukn.name))
    return identifications

# identifications= identify_transform(ref_image, images_to_align, rad= 5, nb=500, verbose=False, visual=False)

def align_images(ref_image, identifications, iraf=True, outdir='alipy_out'):
    outputshape = alipy.align.shape(ref_image)
    for id in identifications:
            if id.ok is True:
                if iraf:
                    alipy.align.irafalign(id.ukn.filepath, id.uknmatchstars,
                                          id.refmatchstars, shape=outputshape,
                                          makepng=False, outdir=outdir)
                else:
                    alipy.align.affineremap(id.ukn.filepath, id.trans,
                                            shape=outputshape, makepng=True,
                                            outdir=outdir)
# register ref to im
def alipyrun(im,ref_image):
	identifications= identify_transform(im, ref_image,
					rad= 5, nb=500, verbose=False, visual=False)
	align_images(im, identifications, iraf=True, outdir='alipy_out')

def alipy_in2ref(ref_image,images_to_align):
    '''
    images_to_align should be a list!
    '''
    identifications= identify_transform(ref_image, images_to_align, rad= 5, nb=500, verbose=False, visual=False)
    align_images(ref_image, identifications, iraf=True, outdir='alipy_out')
    for i in images_to_align :
        newname = 'reg_'+os.path.splitext(i)[0]+os.path.splitext(i)[1]
        os.system('mv alipy_out/'+os.path.splitext(i)[0]+'_gregister'+os.path.splitext(i)[1]+' '+newname)

# match ref image to input image
# ref image will be aligned to input image, no change in input image
# im='Calib-LSGT-NGC3367-20190630-084141-r-180.fits'
# ref_image=['ref.fits']
# output name = reg_Calib-LSGT-NGC3367-20190630-084141-r-180.fits

def alipy_ref2in(im,head='reg_',ref_image=[refim]):
	'''
	ref_image should be a list!
	like ref_image=['ref.fits']
	'''
	newname = head+os.path.splitext(im)[0]+os.path.splitext(im)[1]
	print(im, newname)
	if os.path.isfile(newname):
		os.system('rm '+newname)
		#return 'pass'
	alipyrun(im,ref_image)
	s=os.system('mv alipy_out/'+os.path.splitext(ref_image[0])[0]+
				'_gregister'+os.path.splitext(ref_image[0])[1]+' '+newname)
	if s==0 :
		print('Well done')
	else:
		print('Alipy did not worked')
		print(im, 'stopped')
		return None
	return 'Done'

def puthdr(inim, hdrkey, hdrval, hdrcomment=''):
	from astropy.io import fits
	hdr		=	fits.getheader(inim)
	fits.setval(inim, hdrkey, value=hdrval, comment=hdrcomment)
	comment     = inim+'\t'+'('+hdrkey+'\t'+str(hdrval)+')'

def pixelscale(i):
	cd11 = fits.getheader(i)['CD1_1']
	cd12 = fits.getheader(i)['CD1_2']
	cd21 = fits.getheader(i)['CD2_1']
	cd22 = fits.getheader(i)['CD2_2']
	#pixscale=round(np.sqrt(cd11**2 + cd21**2) *3600 ,4)
	pixscale=np.sqrt(cd11**2 + cd21**2) *3600
	puthdr(i,'PSCALE',pixscale)
	#print('Pixel scale =', pixscale,'\"')
	return pixscale

def remap2min(imlist, refim='ref.fits'):
	os.system('rm remap_'+refim)
	import astropy.io.fits as fits
	import numpy as np
	pslist=[fits.getheader(s)['PSCALE'] for s in imlist]
	print('the least pixelscale =',np.min(pslist))
	os.system('remap -v -p '+str(np.min(pslist)-0.001)+' -o remap_'+refim+' '+refim)
	print('remap_'+refim, pixelscale('remap_'+refim))

def remap2max(imlist, refim='ref.fits'):
	os.system('rm remap_'+refim)
	import astropy.io.fits as fits
	import numpy as np
	pslist=[fits.getheader(s)['PSCALE'] for s in imlist]
	print('the largest pixelscale =',np.max(pslist))
	os.system('remap -v -p '+str(np.max(pslist)+0.001)+' -o remap_'+refim+' '+refim)
	print('remap_'+refim, pixelscale('remap_'+refim))

#remap reference image to input image

def remap_ref2in(im, refim='ref.fits'):
	print ('='*60,'\n','refim', 'to', im)
	os.system('rm rem_'+im)
	remapcom='remap -v '+' -f '+im+' -p '+str(pixelscale(im))+' -o '+'rem_'+im+' '+refim
	os.system(remapcom)
'''
	REMAP WCSTools 3.9.6, 14 May 2020, Jessica Mink (jmink@cfa.harvard.edu)
ERROR: h Argument not recognized
Remap FITS or IRAF images into single FITS image using WCS
Usage: remap [-v][-f WCSfile][-a rot][[-b][-j] ra dec][-i bits][-l num] file1.fit file2.fit ... filen.fit
  or : remap [-v][-f WCSfile][-a rot][[-b][-j] ra dec][-i bits][-l num] @filelist
  -a: Output rotation angle in degrees (default 0)
  -b ra dec: Output center in B1950 (FK4) RA and Dec
  -e long lat: Output center in ecliptic longitude and latitude
  -f file: Use WCS from this file as output WCS
  -g long lat: Output center in galactic longitude and latitude
  -i num: Number of bits per output pixel (default is input)
  -j ra dec: center in J2000 (FK5) RA and Dec
  -l num: Log every num rows of output image
  -m mode: c closest pixel (more to come)
  -n num: integer pixel value for blank pixel
  -o name: Name for output image
  -p secpix: Output plate scale in arcsec/pixel (default =input)
  -s: Set BZERO and BSCALE in output file from input file
  -t: Number of samples per linear output pixel
  -u: Delete distortion keywords from output file
  -v: Verbose
  -w type: Output WCS type (input is default)
  -x x y: Output image reference X and Y coordinates (default is center)
  -y nx ny: Output image dimensions (default is first input image)
'''
# remap input images to reference image
def remap_in2ref(files,ref='ref.fits'):
	remapcom='remap -v -f '+ref+' -p '+str(pixelscale(ref))+' -o rem_'+files+' '+files
	os.system(remapcom)
	inheader=fits.getheader(files)
	output='rem'+files
	outdata,outheader=fits.getdata(output, header=True)
	outheader['DATE-OBS'] = inheader['DATE-OBS']
	fits.writeto(output, outdata, outheader, clobber=True)

def wcsremap(im,refim='ref.fits'):
	#print inim
	outim='rew_'+im
	if os.path.isfile(outim):
		os.system('rm '+outim)
		#print(outim,'exist, Pass')
		#return 'Pass'
		#wcsremapstr='wcsremap -template '+refim+' -source '+im+' -outIm '+outim
		# match to ref image
	if pixelscale(im) >= pixelscale(refim):
		wcsremapstr='wcsremap -template '+im+' -source '+refim+' -outIm '+outim
		print('normal wcsremap run')
		try:
			os.system(wcsremapstr)
			print (outim,'is created')
		except: return None
		return 'Normal'
	else :
		print('WCSTools remap and run wcsremap')
		# os.system('rm '+'remap_'+refim)
		if os.path.isfile('remap_'+refim):
			if pixelscale(im) >= pixelscale('remap_'+refim):
				print('image pixel scale < ref pixelscale', pixelscale(im), '>=', pixelscale(refim))
				print('WCSTools remap and run wcsremap', pixelscale(im),pixelscale('remap_'+refim))
				wcsremapstr='wcsremap -template '+im+' -source '+'remap_'+refim+' -outIm '+outim
				try:
					os.system(wcsremapstr)
					print (outim,'is created')
					puthdr(outim,'COMMENT','Remapped reference used')
				except: return None

		else:
			print('make least pixelscale remap_ref.fits first!')
			return None

def wcsremap_im2ref(im,refim='ref.fits'):
	#print inim
	outim='rew_'+im
	if os.path.isfile(outim):
		os.system('rm '+outim)
		#print(outim,'exist, Pass')
		#return 'Pass'
		#wcsremapstr='wcsremap -template '+refim+' -source '+im+' -outIm '+outim
		# match to ref image
	if pixelscale(refim) >= pixelscale(im):
		wcsremapstr='wcsremap -template '+refim+' -source '+im+' -outIm '+outim
		print('normal wcsremap run')
		try:
			os.system(wcsremapstr)
			print (outim,'is created')
		except: return None
		return 'Normal'
	else :
		print('WCSTools remap and run wcsremap')
		# os.system('rm '+'remap_'+refim)
		if os.path.isfile('remap_'+refim):
			if pixelscale('remap_'+refim) >= pixelscale(im):
				print('image pixel scale < ref pixelscale', pixelscale(refim), '>=', pixelscale(im))
				print('WCSTools remap and run wcsremap', 'input',pixelscale(im),'remap ref',pixelscale('remap_'+refim))
				wcsremapstr='wcsremap -template '+'remap_'+refim+' -source '+im+' -outIm '+outim
				try:
					os.system(wcsremapstr)
					print (outim,'is created')
					puthdr(outim,'COMMENT','Remapped reference used')
				except: return None

		else:
			print('make least pixelscale remap_ref.fits first!')
			return None

def wcsremap_alipyref2in(im, refim='ref.fits', gregister=True):
	#print inim
	outim='rew_'+im
	print('='*60,'\n')
	if os.path.isfile(outim):
		os.system('rm '+outim)
		#print(outim,'exist, Pass')
		#return 'Pass'
		#wcsremapstr='wcsremap -template '+refim+' -source '+im+' -outIm '+outim
		# match to ref image
	if pixelscale(im) >= pixelscale(refim):
		wcsremapstr='wcsremap -template '+im+' -source '+refim+' -outIm '+outim
		print('normal wcsremap run')
		try:
			os.system(wcsremapstr)
			print (outim,'is created')
			puthdr(outim,'COMMENT','wcsremap, normal')
		except: return None
		return 'Normal'
	else :
		if gregister!=True:
			print('WCSTools remap and run wcsremap')
			# os.system('rm '+'remap_'+refim)
			if os.path.isfile('remap_'+refim):
				if pixelscale(im) >= pixelscale('remap_'+refim):
					print('image pixel scale < ref pixelscale', pixelscale(im), '>=', pixelscale(refim))
					print('WCSTools remap and run wcsremap', pixelscale(im),pixelscale('remap_'+refim))
					wcsremapstr='wcsremap -template '+im+' -source '+'remap_'+refim+' -outIm '+outim
					try:
						os.system(wcsremapstr)
						print (outim,'is created')
						puthdr(outim,'COMMENT','wcsremap, Remapped reference used')
					except: return None
			else:
				print('make least pixelscale remap_ref.fits first!')
				return None
		else:
			print('Alipy_ref2in will be used')
			alipy_ref2in(im,head='rew_',ref_image=[refim])
			puthdr(outim,'COMMENT','alipy_ref2in, with normal reference')

#wcstools remap
# remap -v -p 0.8 -o remap_r.fits r.fits
# template plate scale > image plate scale : safe result
# template plate scale < image plate scale : resampling or alipy

# for inim in inlist :
# 	wcsremap(im,refim='ref.fits')
def remap_pix(im,pix):
	print('='*60,'\n',im,'remapping','\n')
	remap='remap -v -p '+str(pix)+' -o rem_'+im+' '+im
	os.system(remap)

'''
if __name__ == '__main__' :
	p=Pool(2)
	p.map(wcsremap,inlist)

'''
print('Done.\a')


from itertools import chain

from django.forms.widgets import (
    CheckboxSelectMultiple,
    CheckboxInput,
    RadioSelect,
    TextInput,
    TimeInput,
)
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape, format_html, html_safe

@html_safe
class SubWidget(object):
    """
    Some widgets are made of multiple HTML elements -- namely, RadioSelect.
    This is a class that represents the "inner" HTML element of a widget.
    """

    def __init__(self, parent_widget, name, value, attrs, choices):
        self.parent_widget = parent_widget
        self.name, self.value = name, value
        self.attrs, self.choices = attrs, choices

    def __str__(self):
        args = [self.name, self.value, self.attrs]
        if self.choices:
            args.append(self.choices)
        return self.parent_widget.render(*args)

@html_safe
class ChoiceInput(SubWidget):
    """
    An object used by ChoiceFieldRenderer that represents a single
    <input type='$input_type'>.
    """

    input_type = None  # Subclasses must define this

    def __init__(self, name, value, attrs, choice, index):
        self.name = name
        self.value = value
        self.attrs = attrs
        self.choice_value = force_text(choice[0])
        self.choice_label = force_text(choice[1])
        self.index = index
        if "id" in self.attrs:
            self.attrs["id"] += "_%d" % self.index

    def __str__(self):
        return self.render()

    def render(self, name=None, value=None, attrs=None):
        if self.id_for_label:
            label_for = format_html(' for="{}"', self.id_for_label)
        else:
            label_for = ""
        attrs = dict(self.attrs, **attrs) if attrs else self.attrs
        return format_html(
            "{} {}", label_for, self.tag(attrs), self.choice_label
        )

    def is_checked(self):
        return self.value == self.choice_value

    def tag(self, attrs=None):
        attrs = attrs or self.attrs
        final_attrs = dict(
            attrs, type=self.input_type, name=self.name, value=self.choice_value
        )
        if self.is_checked():
            final_attrs["checked"] = "checked"
        return format_html("<input{} />", flatatt(final_attrs))

    @property
    def id_for_label(self):
        return self.attrs.get("id", "")

class RadioChoiceInput(ChoiceInput):
    input_type = "radio"

    def __init__(self, *args, **kwargs):
        super(RadioChoiceInput, self).__init__(*args, **kwargs)
        self.value = force_text(self.value)

class CheckboxSelectMultipleWithIcon(CheckboxSelectMultiple):
    def render(self, name, value, attrs=None, renderer=None, choices=()):
        if value is None:
            value = []
        has_id = attrs and "id" in attrs
        final_attrs = self.build_attrs(attrs)
        output = ["
"]
        str_values = set([str(v) for v in value])
        for (i, (option_value, option_label)) in enumerate(
            chain(self.choices, choices)
        ):
            if has_id:
                final_attrs = dict(final_attrs, id="%s_%s" % (attrs["id"], i))
                label_for = ' for="%s"' % final_attrs["id"]
            else:
                label_for = ""
            cb = CheckboxInput(
                final_attrs, check_test=lambda value: str(value) in str_values
            )
            rendered_cb = cb.render(name, option_value)
            option_label = conditional_escape(option_label)
            x = option_label.split("|")
            if len(x) > 1:
                icon = x[0]
                option_label = x[1]
            else:
                icon = None
            if icon:
                image = "" % icon
            else:
                image = ""
            output.append(
                "
%s %s %s
"
                % (label_for, rendered_cb, image, option_label)
            )
        output.append("
")
        return mark_safe("\n".join(output))

class RadioInput2(RadioChoiceInput):
    def __str__(self):
        if "id" in self.attrs:
            label_for = ' for="%s_%s"' % (self.attrs["id"], self.index)
        else:
            label_for = ""
        choice_label = conditional_escape(self.choice_label)
        x = choice_label.split("|")
        if len(x) > 1:
            label = "   " % x[0] + x[1]
        else:
            label = x[0]
        self.attrs["class"] = "radioselectwithicon"
        return mark_safe("
%s %s
" % (self.tag(), label))

class RadioFieldRendererWithIcon(object):
    """An object used by RadioSelect to enable customization of radio widgets."""

    def __init__(self, name, value, attrs, choices):
        (self.name, self.value, self.attrs) = (name, value, attrs)
        self.choices = choices

    def __iter__(self):
        for (i, choice) in enumerate(self.choices):
            yield RadioInput2(self.name, self.value, self.attrs.copy(), choice, i)

    def __getitem__(self, idx):
        choice = self.choices[idx]
        return RadioInput2(self.name, self.value, self.attrs.copy(), choice, idx)

    def __str__(self):
        return self.render()

    def render(self):
        """Outputs a
 for this set of radio fields."""
        return mark_safe(
            "
%s
"
            % " ".join(['
%s
' % w for w in self])
        )

class RadioSelectWithIcon(RadioSelect):
    renderer = RadioFieldRendererWithIcon


# install py-solc-x for compiling solidity file
# Deployed on Ganache-CLI
import os
import json
from web3 import Web3
from dotenv import load_dotenv
from solcx import compile_standard, install_solc
install_solc("0.6.0")

load_dotenv()

# Getting file
with open("./SimpleStorage.sol", 'r') as file:
    simple_storage_file = file.read()

# Compile our solidity code

compiled_sol = compile_standard(
    {
        "language": "Solidity",
        "sources": {"SimpleStorage.sol": {"content": simple_storage_file}},
        "settings": {
            "outputSelection": {
                "*": {
                    "*": ['abi', 'metadata', 'evm.bytecode', 'evm.sourceMap']
                }
            }
        }
    },
    solc_version="0.6.0",
)

with open("compiled__code.json", 'w') as file:
    json.dump(compiled_sol, file)

# get bytecode
# here we are just extracting the data from our compiled solidity code
bytecode = compiled_sol["contracts"]["SimpleStorage.sol"]["SimpleStorage"]["evm"]["bytecode"]["object"]

# get abi
abi = compiled_sol["contracts"]["SimpleStorage.sol"]["SimpleStorage"]["abi"]

# for connecting to ganache

# HTTP Provider (for connecting to blockchain)
w3 = Web3(Web3.HTTPProvider("HTTP://127.0.0.1:8545"))
print("Blockchain Connected....")
# Our credentials
chain_id = 1337
my_address = os.getenv("MY_ADDRESS")
private_key = os.getenv("PRIVATE_KEY")

# Create Contract in Python
SimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode)
# print(SimpleStorage)
# This will print <class 'web3._utils.datatypes.Contract'>
print("Contract created using bytecode and abi")
# Get latest transaction
nonce = w3.eth.getTransactionCount(my_address)
# print(nonce)

# 1. Build a Transaction
# 2. Sign a Transaction
# 3. Send a Transaction

# transaction building
transaction = SimpleStorage.constructor().buildTransaction({
    "chainId": chain_id,
    "from": my_address,
    "nonce": nonce,
    "gasPrice": w3.eth.gas_price
})
print("Transaction build successfull 🎯")

# signing the transaction
signed_transaction = w3.eth.account.sign_transaction(
    transaction, private_key=private_key)
# print(signed_transaction)

# sending the signed transaction
transaction_hash = w3.eth.send_raw_transaction(
    signed_transaction.rawTransaction)

# wait for block confirmations
transaction_recipt = w3.eth.wait_for_transaction_receipt(transaction_hash)
# print(transaction_recipt)
print("Transaction success ✅")

# Working with the Contract ->

# for working with contract we always need :
# * Contract Address
# * Contract ABI

# Getting the deployed contract
simple_storage = w3.eth.contract(
    address=transaction_recipt.contractAddress, abi=abi)

print("Contract for interaction initialised 🗳")

# We can interact in two ways with our Contract :
# Call -> Simulate making the call and getting the value (no state change involved)
# Transact -> actually make a state change

# initial value of favoriteNumber (from contract)
print("-------------------------------------------")
print("Initial value (Favorite Number) : ")
print(simple_storage.functions.retrieve().call())
print("-------------------------------------------")
# print(simple_storage.functions.store(15).call())

# how to make a transaction on our contract
storage_transaction = simple_storage.functions.store(15).buildTransaction({
    "chainId": chain_id,
    "from": my_address,
    "nonce": nonce + 1,
    "gasPrice": w3.eth.gas_price
})
signed_storage_transaction = w3.eth.account.sign_transaction(
    storage_transaction, private_key=private_key
)
send_storage_transaction = w3.eth.send_raw_transaction(
    signed_storage_transaction.rawTransaction)
print("Store(15) transaction done ✅")

transaction_recipt = w3.eth.wait_for_transaction_receipt(
    send_storage_transaction)
print("Transaction Recipt ->")
print(transaction_recipt)

print("-------------------------------------------")
print("Final value (Favorite Number) : ")
print(simple_storage.functions.retrieve().call())
print("-------------------------------------------")