# Preamble to mimick book environment
import logging
from pprint import pprint
from sys import stdout as STD

OUT

import app

class Dialog(object):
    def __init__(self):
        pass

save_dialog = Dialog()

def show():
    print('Showing the dialog!')

def configure():
    save_dialog.save_dir = app.prefs.get('save_dir')


"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):
        return 'Notifications'

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Since Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []
        for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })
        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():
    data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'
    title = 'Notifications'
    visualization = analytics.Visualization(
        name, title, 'stats.html',
        data_source_classes=[NotificationsDataSource])
    dashboard.DashboardHandler.add_sub_nav_mapping(
        'analytics', name, title, action='analytics_notifications',
        contents=analytics.TabRenderer([visualization]))


"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

    def entity_class(self):
        return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Since Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []
        for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })
        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():
    data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'
    title = 'Notifications'
    visualization = analytics.Visualization(
        name, title, 'stats.html',
        data_source_classes=[NotificationsDataSource])
    dashboard.DashboardHandler.add_sub_nav_mapping(
        'analytics', name, title, action='analytics_notifications',
        contents=analytics.TabRenderer([visualization]))


data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'

"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

    def entity_class(self):
        return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):
        return 'Notifications'

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Since Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []
        for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })
        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():

    title = 'Notifications'
    visualization = analytics.Visualization(
        name, title, 'stats.html',
        data_source_classes=[NotificationsDataSource])
    dashboard.DashboardHandler.add_sub_nav_mapping(
        'analytics', name, title, action='analytics_notifications',
        contents=analytics.TabRenderer([visualization]))


"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

    def entity_class(self):
        return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):
        return 'Notifications'

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Since Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []
        for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })
        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():
    data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'

    visualization = analytics.Visualization(
        name, title, 'stats.html',
        data_source_classes=[NotificationsDataSource])
    dashboard.DashboardHandler.add_sub_nav_mapping(
        'analytics', name, title, action='analytics_notifications',
        contents=analytics.TabRenderer([visualization]))


visualization = analytics.Visualization(
        name, title, 'stats.html',
        data_source_classes=[NotificationsDataSource])
    dashboard.DashboardHandler.add_sub_nav_mapping(
        'analytics', name, title, action='analytics_notifications',
        contents=analytics.TabRenderer([visualization]))

"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

    def entity_class(self):
        return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):
        return 'Notifications'

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Since Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []
        for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })
        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():
    data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'
    title = 'Notifications'


"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

    def entity_class(self):
        return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):
        return 'Notifications'

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Since Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []
        for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })
        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():
    data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'
    title = 'Notifi


for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })

"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

    def entity_class(self):
        return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):
        return 'Notifications'

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Since Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []

        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():
    data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'
    title = 'Notifications'
    visualization = analytics.Visualization(
        name, title, 'stats.html',
        data_source_classes=[NotificationsDataSource])
    dashboard.DashboardHandler.add_sub_nav_mapping(
        'analytics', name, title, action='analytics_notifications',
        contents=analytics.TabRenderer([visualization]))


"""Stats generation for the notifications module."""

__author__ = [
    'example@nnthink.com (John Cox)',
]

import ast
import datetime

from common import schema_fields
from models import analytics
from models import data_sources
from models import jobs
from modules.dashboard import dashboard
from modules.notifications import notifications

class NotificationCountsGenerator(jobs.AbstractCountingMapReduceJob):

    @staticmethod
    def get_description():
        return 'notifications'

    def entity_class(self):
        return notifications.Notification

    @staticmethod
    def map(notification):
        yield (
            notifications.Status.from_notification(notification).state,
            # Treating as module-protected. pylint: disable=protected-access
            notification._enqueue_date.date().toordinal()
            ), 1

class NotificationsDataSource(
    data_sources.AbstractSmallRestDataSource,
    data_sources.SynchronousQuery):

    @classmethod
    def get_name(cls):
        return 'notifications'

    @classmethod
    def get_title(cls):
        return 'Notifications'

    @staticmethod
    def required_generators():
        return [NotificationCountsGenerator]

    @classmethod
    def get_schema(cls, app_context, log, source_context):
        ret = schema_fields.FieldRegistry('notifications')
        ret.add_property(schema_fields.SchemaField(
            'timestamp_millis', 'Millisceonds Si

nce Epoch', 'integer'))
        ret.add_property(schema_fields.SchemaField(
            'status', 'Status', 'string'))
        ret.add_property(schema_fields.SchemaField(
            'count', 'Count', 'integer'))
        return ret.get_json_schema_dict()['properties']

    @classmethod
    def fetch_values(cls, app_context, source_context, schema, log, page_number,
                     job):
        epoch = datetime.date(year=1970, month=1, day=1)
        ret = []
        for key, count in jobs.MapReduceJob.get_results(job):
            status, date_ordinal = ast.literal_eval(key)
            date = datetime.date.fromordinal(date_ordinal)
            timestamp_millis = int((date - epoch).total_seconds()) * 1000
            ret.append({
                'timestamp_millis': timestamp_millis,
                'status': status,
                'count': count,
            })
        return ret, page_number

    @staticmethod
    def fill_values(app_context, template_values, job):
        template_values['any_notifications'] = bool(
            jobs.MapReduceJob.get_results(job))

def register_analytic():
    data_sources.Registry.register(NotificationsDataSource)
    name = 'notifications'
    title = 'Notifications'
    visualization = analytics.Visualization(
        name, title, 'stats.html',
        data_source_classes=[NotificationsDataSource])
    dashboard.DashboardHandler.add_sub_nav_mapping(
        'analytics', name, title, action='analytics_notifications',
        contents=analytics.TabRenderer([visualization]))


""" Primitive module for tracking running statistics without storing values in
memory.
"""

class StatisticsTracker:

    def __init__(self):
        self.min = None
        self.max = None
        self.count = 0
        self.sum = 0

if self.min is None or value < self.min:
            self.min = value
        if self.max is None or value > self.max:
            self.max = value
        self.count += 1
        self.sum += value

    @property
    def avg(self):
        if self.count > 0:
            return self.sum / self.count
        else:
            return None


self.min = None
        self.max = None
        self.count = 0
        self.sum = 0

""" Primitive module for tracking running statistics without storing values in
memory.
"""

class StatisticsTracker:

    def __init__(self):

    def track(self, value):
        if self.min is None or value < self.min:
            self.min = value
        if self.max is None or value > self.max:
            self.max = value
        self.count += 1
        self.sum += value

    @property
    def avg(self):
        if self.count > 0:
            return self.sum / self.count
        else:
            return None


""" Primitive module for tracking running statistics without storing values in
memory.
"""

class StatisticsTracker:

    def __init__(self):
        self.min = None
        self.max = None
        self.count = 0
        self.sum = 0

    def track(self, value):
        if self.min is None or value < self.min:
            self.min = value
        if self.max is None or value > self.max:
            self.max = value
        self.count += 1
        self.su

    @property
    def avg(self):
        if self.count > 0:
            return self.sum / self.count
        else:
            return None


if self.count > 0:
            return self.sum / self.count
        else:
            return None

""" Primitive module for tracking running statistics without storing values in
memory.
"""

class StatisticsTracker:

    def __init__(self):
        self.min = None
        self.max = None
        self.count = 0
        self.sum = 0

    def track(self, value):
        if self.min is None or value < self.min:
            self.min = value
        if self.max is None or value > self.max:
            self.max = value
        self.count += 1
        self.sum += value

    @property
    def avg(self):


""" Primitive module for tracking running statistics without storing values in
memory.
"""

class StatisticsTracker:

    def __init__(self):
        self.min = None
        self.max = None
        self.count = 0
        self.sum = 0

    def track(self, value):
        if self.min is None or value < self.min:
            self.min = value
        if self.max is None or value > self.max:
            self.max = value
        self.count += 1
        self.sum += value

    @pr

operty
    def avg(self):
        if self.count > 0:
            return self.sum / self.count
        else:
            return None


import math

import torch

class ConfusionMatrix(object):

    def __init__(self, dim):
        self.dim = dim
        self.matrix = torch.zeros(dim, dim)

    def ingest(self, scores, gt_labels):
        pred_labels = scores.max(1)[1]
        for pred_label, gt_label in zip(pred_labels.tolist(), gt_labels.tolist()):
            self.matrix[pred_label, gt_label] += 1

    @property
    def acc(self):
        return (self.matrix.diag().sum() / self.matrix.sum()).item()

    @property
    def metrics(self):
        return dict(acc=self.acc)

    def __repr__(self):
        return repr(self.matrix)

class BinaryConfusionMatrix(ConfusionMatrix):

    def __init__(self):
        super().__init__(2)

    @property
    def fp(self):
        return self.matrix[1, 0].item()

    @property

return self.matrix[0, 1].item()

    @property
    def tp(self):
        return self.matrix[1, 1].item()

    @property
    def tn(self):
        return self.matrix[0, 0].item()

    @property
    def metrics(self):
        return dict(tp=self.tp, tn=self.fp, fp=self.fn, fn=self.tn, mcc=self.mcc, acc=self.acc)

    @property
    def mcc(self):
        num = self.tp * self.tn - self.fp * self.fn
        denom = math.sqrt((self.tp + self.fp) * (self.tp + self.fn) * \
            (self.tn + self.fp) * (self.tn + self.fn))
        if denom == 0:
            return 0.
        return num / denom


return (self.matrix.diag().sum() / self.matrix.sum()).item()

import math

import torch

class ConfusionMatrix(object):

    def __init__(self, dim):
        self.dim = dim
        self.matrix = torch.zeros(dim, dim)

    def ingest(self, scores, gt_labels):
        pred_labels = scores.max(1)[1]
        for pred_label, gt_label in zip(pred_labels.tolist(), gt_labels.tolist()):
            self.matrix[pred_label, gt_label] += 1

    @property
    def acc(self):

    @property
    def metrics(self):
        return dict(acc=self.acc)

    def __repr__(self):
        return repr(self.matrix)

class BinaryConfusionMatrix(ConfusionMatrix):

    def __init__(self):
        super().__init__(2)

    @property
    def fp(self):
        return self.matrix[1, 0].item()

    @property
    def fn(self):
        return self.matrix[0, 1].item()

    @property
    def tp(self):
        return self.matrix[1, 1].item()

    @property
    def tn(self):
        return self.matrix[0, 0].item()

    @property
    def metrics(self):
        return dict(tp=self.tp, tn=self.fp, fp=self.fn, fn=self.tn, mcc=self.mcc, acc=self.acc)

    @property
    def mcc(self):
        num = self.tp * self.tn - self.fp * self.fn
        denom = math.sqrt((self.tp + self.fp) * (self.tp + self.fn) * \
            (self.tn + self.fp) * (self.tn + self.fn))
        if denom == 0:
            return 0.
        return num / denom


import math

import torch

class ConfusionMatrix(object):

    def __init__(self, dim):
        self.dim = dim
        self.matrix = torch.zeros(dim, dim)

    def ingest(self, scores, gt_labels):
        pred_labels = scores.max(1)[1]
        for pred_label, gt_label in zip(pred_labels.tolist(), gt_labels.tolist()):
            self.matrix[pred_label, gt_label] += 1

    @property
    def acc(self):
        return (s


import math

import torch

class ConfusionMatrix(object):

    def __init__(self, dim):
        self.dim = dim
        self.matrix = torch.zeros(dim, dim)

    def ingest(self, scores, gt_labels):
        pred_labels = scores.max(1)[1]
        for pred_label, gt_label in zip(pred_labels.tolist(), gt_labels.tolist()):
            self.matrix[pred_label, gt_label] += 1

    @property
    def acc(self):
        return (self.matrix.diag().sum() / self.matrix.sum()).item()

    @property
    def metrics(self):
        return dict(acc=self.acc)

    def __repr__(self):
        return repr(self.matrix)

class BinaryConfusionMatrix(ConfusionMatrix):

    def __init__(self):
        super().__init__(2)

    @property
    def fp(self):
        return self.matrix[1, 0].item()

    @property
    def fn(self):
        return self.matrix[0, 1].item()

    @property
    def tp(self):
        return self.matrix[1, 1].item()

    @property
    def tn(self):
        return self.matrix[0, 0].item()

    @property
    def metrics(self):
        return dict(tp=self.tp, tn=self.fp, fp=self.fn, fn=self.tn, mcc=self.mcc, acc=self.acc)

    @property
    def mcc(self):
        num = self.tp * self.tn - self.fp * self.fn
        denom = math.sqrt((self.tp + self.fp) * (self.tp + self.fn) * \
            (self.tn + self.fp) * (self.tn + self.fn))


for pred_label, gt_label in zip(pred_labels.tolist(), gt_labels.tolist()):
            self.matrix[pred_label, gt_label] += 1

import math

import torch

class ConfusionMatrix(object):

    def __init__(self, dim):
        self.dim = dim
        self.matrix = torch.zeros(dim, dim)

    def ingest(self, scores, gt_labels):
        pred_labels = scores.max(1)[1]

    @property
    def acc(self):
        return (self.matrix.diag().sum() / self.matrix.sum()).item()

    @property
    def metrics(self):
        return dict(acc=self.acc)

    def __repr__(self):
        return repr(self.matrix)

class BinaryConfusionMatrix(ConfusionMatrix):

    def __init__(self):
        super().__init__(2)

    @property
    def fp(self):
        return self.matrix[1, 0].item()

    @property
    def fn(self):
        return self.matrix[0, 1].item()

    @property
    def tp(self):
        return self.matrix[1, 1].item()

    @property
    def tn(self):
        return self.matrix[0, 0].item()

    @property
    def metrics(self):
        return dict(tp=self.tp, tn=self.fp, fp=self.fn, fn=self.tn, mcc=self.mcc, acc=self.acc)

    @property
    def mcc(self):
        num = self.tp * self.tn - self.fp * self.fn
        denom = math.sqrt((self.tp + self.fp) * (self.tp + self.fn) * \
            (self.tn + self.fp) * (self.tn + self.fn))
        if denom == 0:
            return 0.
        return num / denom


import math

import torch

class ConfusionMatrix(object):

    def __init__(self, dim):
        self.dim = dim
        self.matrix = torch.zeros(dim, dim)

    def ingest(self, scores, gt_labels):
        pred_labels = scores.max(1)[1]
        for pred_label, gt_label in zip(pred_labels.tolist(), gt_labels.tolist()):
            self.matrix[pred_label, gt_label] += 1

    @property
    def acc(self):
        return (self.matrix.diag().sum() / self.matrix.sum()).item()

    @property
    def metrics(self):
        return dict(acc=self.acc)

    def __repr__(self):
        return repr(self.matrix)

class BinaryConfusionMatrix(ConfusionMatrix):

    def __init__(self):
        super().__init__(2)

    @property
    def fp(self):

       return self.matrix[1, 0].item()

    @property
    def fn(self):
        return self.matrix[0, 1].item()

    @property
    def tp(self):
        return self.matrix[1, 1].item()

    @property
    def tn(self):
        return self.matrix[0, 0].item()

    @property
    def metrics(self):
        return dict(tp=self.tp, tn=self.fp, fp=self.fn, fn=self.tn, mcc=self.mcc, acc=self.acc)

    @property
    def mcc(self):
        num = self.tp * self.tn - self.fp * self.fn
        denom = math.sqrt((self.tp + self.fp) * (self.tp + self.fn) * \
            (self.tn + self.fp) * (self.tn + self.fn))
        if denom == 0:
            return 0.
        return num / denom


def webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):

from PyObjCTools.TestSupport import TestCase, min_os_level
import WebKit  # noqa: F401
import objc

class TestWKUIDelegateHelper(WebKit.NSObject):
    def webView_createWebViewWithConfiguration_forNavigationAction_windowFeatures_(
        self, w, c, a, f
    ):
        return None

pass

    def webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_(  # noqa: B950
        self, w, p, d, f, h
    ):
        pass

    def webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_(
        self, w, p, f, c
    ):
        pass

    def webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

    def webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

class TestWKUIDelegate(TestCase):
    @min_os_level("10.10")
    def testProtocols10_10(self):
        p = objc.protocolNamed("WKUIDelegate")
        self.assertIsInstance(p, objc.formal_protocol)

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_,  # noqa: B950
            4,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v@",
        )

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )

    def test_constants(self):
        self.assertEqual(WebKit.WKPermissionDecisionPrompt, 0)
        self.assertEqual(WebKit.WKPermissionDecisionGrant, 1)
        self.assertEqual(WebKit.WKPermissionDecisionDeny, 2)

        self.assertEqual(WebKit.WKMediaCaptureTypeCamera, 0)
        self.assertEqual(WebKit.WKMediaCaptureTypeMicrophone, 1)
        self.assertEqual(WebKit.WKMediaCaptureTypeCameraAndMicrophone, 2)


from PyObjCTools.TestSupport import TestCase, min_os_level
import WebKit  # noqa: F401
import objc

class TestWKUIDelegateHelper(WebKit.NSObject):
    def webView_createWebViewWithConfiguration_forNavigationAction_windowFeatures_(
        self, w, c, a, f
    ):
        return None

    def webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_(  # noqa: B950
        self, w, p, d, f, h
    ):
        pass

    def webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_(
        self, w, p, f, c
    ):

    def webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

    def webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

class TestWKUIDelegate(TestCase):
    @min_os_level("10.10")
    def testProtocols10_10(self):
        p = objc.protocolNamed("WKUIDelegate")
        self.assertIsInstance(p, objc.formal_protocol)

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_,  # noqa: B950
            4,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v@",
        )

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )

    def test_constants(self):
        self.assertEqual(WebKit.WKPermissionDecisionPrompt, 0)
        self.assertEqual(WebKit.WKPermissionDecisionGrant, 1)
        self.assertEqual(WebKit.WKPermissionDecisionDeny, 2)

        self.assertEqual(WebKit.WKMediaCaptureTypeCamera, 0)
        self.assertEqual(WebKit.WKMediaCaptureTypeMicrophone, 1)
        self.assertEqual(WebKit.WKMediaCaptureTypeCameraAndMicrophone, 2)


self.assertEqual(WebKit.WKPermissionDecisionPrompt, 0)
        self.assertEqual(WebKit.WKPermissionDecisionGrant, 1)

from PyObjCTools.TestSupport import TestCase, min_os_level
import WebKit  # noqa: F401
import objc

class TestWKUIDelegateHelper(WebKit.NSObject):
    def webView_createWebViewWithConfiguration_forNavigationAction_windowFeatures_(
        self, w, c, a, f
    ):
        return None

    def webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_(  # noqa: B950
        self, w, p, d, f, h
    ):
        pass

    def webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_(
        self, w, p, f, c
    ):
        pass

    def webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

    def webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

class TestWKUIDelegate(TestCase):
    @min_os_level("10.10")
    def testProtocols10_10(self):
        p = objc.protocolNamed("WKUIDelegate")
        self.assertIsInstance(p, objc.formal_protocol)

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_,  # noqa: B950
            4,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v@",
        )

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )

    def test_constants(self):

        self.assertEqual(WebKit.WKPermissionDecisionDeny, 2)

        self.assertEqual(WebKit.WKMediaCaptureTypeCamera, 0)
        self.assertEqual(WebKit.WKMediaCaptureTypeMicrophone, 1)
        self.assertEqual(WebKit.WKMediaCaptureTypeCameraAndMicrophone, 2)


self.assertEqual(WebKit.WKPermissionDecisionDeny, 2)

        self.assertEqual(WebKit.WKMediaCaptureTypeCamera, 0)

from PyObjCTools.TestSupport import TestCase, min_os_level
import WebKit  # noqa: F401
import objc

class TestWKUIDelegateHelper(WebKit.NSObject):
    def webView_createWebViewWithConfiguration_forNavigationAction_windowFeatures_(
        self, w, c, a, f
    ):
        return None

    def webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_(  # noqa: B950
        self, w, p, d, f, h
    ):
        pass

    def webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_(
        self, w, p, f, c
    ):
        pass

    def webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

    def webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

class TestWKUIDelegate(TestCase):
    @min_os_level("10.10")
    def testProtocols10_10(self):
        p = objc.protocolNamed("WKUIDelegate")
        self.assertIsInstance(p, objc.formal_protocol)

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_,  # noqa: B950
            4,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v@",
        )

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )

    def test_constants(self):
        self.assertEqual(WebKit.WKPermissionDecisionPrompt, 0)
        self.assertEqual(WebKit.WKPermissionDecisionGrant, 1)

        self.assertEqual(WebKit.WKMediaCaptureTypeMicrophone, 1)
        self.assertEqual(WebKit.WKMediaCaptureTypeCameraAndMicrophone, 2)


self.assertEqual(WebKit.WKMediaCaptureTypeMicrophone, 1)
        self.assertEqual(WebKit.WKMediaCaptureTypeCameraAndMicrophone, 2)

from PyObjCTools.TestSupport import TestCase, min_os_level
import WebKit  # noqa: F401
import objc

class TestWKUIDelegateHelper(WebKit.NSObject):
    def webView_createWebViewWithConfiguration_forNavigationAction_windowFeatures_(
        self, w, c, a, f
    ):
        return None

    def webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_(  # noqa: B950
        self, w, p, d, f, h
    ):
        pass

    def webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_(
        self, w, p, f, c
    ):
        pass

    def webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

    def webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

class TestWKUIDelegate(TestCase):
    @min_os_level("10.10")
    def testProtocols10_10(self):
        p = objc.protocolNamed("WKUIDelegate")
        self.assertIsInstance(p, objc.formal_protocol)

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_,  # noqa: B950
            4,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v@",
        )

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )

    def test_constants(self):
        self.assertEqual(WebKit.WKPermissionDecisionPrompt, 0)
        self.assertEqual(WebKit.WKPermissionDecisionGrant, 1)
        self.assertEqual(WebKit.WKPermissionDecisionDeny, 2)

        self.assertEqual(WebKit.WKMediaCaptureTypeCamera, 0)


from PyObjCTools.TestSupport import TestCase, min_os_level
import WebKit  # noqa: F401
import objc

class TestWKUIDelegateHelper(WebKit.NSObject):
    def webView_createWebViewWithConfiguration_forNavigationAction_windowFeatures_(
        self, w, c, a, f
    ):
        return None

    def webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_(  # noqa: B950
        self, w, p, d, f, h
    ):
        pass

    def webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_(
        self, w, p, f, c
    ):
        pass

    def webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

    def webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

class TestWKUIDelegate(TestCase):
    @min_os_level("10.10")
    def testProtocols10_10(self):
        p = objc.protocolNamed("WKUIDelegate")
        self.assertIsInstance(p, objc.formal_protocol)

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_,  # noqa: B950
            4,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v@",
        )

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )

    def test_constants(self):
        self.assertEqual(WebKit.WKPermissionDecisionPrompt, 0)
        self.assertEqual(WebKit.WKPermissionDecisionGrant, 1)
        self.assertEqua

        self.assertEqual(WebKit.WKMediaCaptureTypeCamera, 0)
        self.assertEqual(WebKit.WKMediaCaptureTypeMicrophone, 1)
        self.assertEqual(WebKit.WKMediaCaptureTypeCameraAndMicrophone, 2)


from PyObjCTools.TestSupport import TestCase, min_os_level
import WebKit  # noqa: F401
import objc

class TestWKUIDelegateHelper(WebKit.NSObject):
    def webView_createWebViewWithConfiguration_forNavigationAction_windowFeatures_(
        self, w, c, a, f
    ):
        return None

    def webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_(
        self, w, m, f, h
    ):
        pass

    def webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_(  # noqa: B950
        self, w, p, d, f, h
    ):
        pass

    def webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_(
        self, w, p, f, c
    ):
        pass

    def webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

    def webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_(
        self, a, b, c, d, e
    ):
        pass

class TestWKUIDelegate(TestCase):
    @min_os_level("10.10")
    def testProtocols10_10(self):
        p = objc.protocolNamed("WKUIDelegate")
        self.assertIsInstance(p, objc.formal_protocol)

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptAlertPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptConfirmPanelWithMessage_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runJavaScriptTextInputPanelWithPrompt_defaultText_initiatedByFrame_completionHandler_,  # no

qa: B950
            4,
            b"v",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_runOpenPanelWithParameters_initiatedByFrame_completionHandler_,  # noqa: B950
            3,
            b"v@",
        )

        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestMediaCapturePermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )
        self.assertArgIsBlock(
            TestWKUIDelegateHelper.webView_requestDeviceOrientationAndMotionPermissionForOrigin_initiatedByFrame_type_decisionHandler_,  # noqa: B950
            4,
            b"vq",
        )

    def test_constants(self):
        self.assertEqual(WebKit.WKPermissionDecisionPrompt, 0)
        self.assertEqual(WebKit.WKPermissionDecisionGrant, 1)
        self.assertEqual(WebKit.WKPermissionDecisionDeny, 2)

        self.assertEqual(WebKit.WKMediaCaptureTypeCamera, 0)
        self.assertEqual(WebKit.WKMediaCaptureTypeMicrophone, 1)
        self.assertEqual(WebKit.WKMediaCaptureTypeCameraAndMicrophone, 2)


subreddit = 'AmongUs'
t_channel = '@r_AmongUs'


subreddit = 'AmongUs'
t_channel = '@r_AmongUs'

def send_post(submission, r2t):


subreddit = 'AmongUs'
t_channel = '@r_AmongUs'

def send_post(submission, r2t):
    return r


subreddit = 'AmongUs'
t_channel = '@r_AmongUs'

def send_post(submission, r2t):
    return r2t.se


"""Add cert_uuuid to bay

Revision ID: 6f21dc920bb
Revises: 966a99e70ff
Create Date: 2015-08-19 13:57:14.863292

"""

# revision identifiers, used by Alembic.
revision = '6f21dc920bb'
down_revision = '966a99e70ff'

from alembic import op  # noqa: E402
import sqlalchemy as sa  # noqa: E402

op.add_column(
        'bay',
        sa.Column('ca_cert_uuid', sa.String(length=36), nullable=True))
    op.add_column(
        'bay',
        sa.Column('magnum_cert_uuid', sa.String(length=36), nullable=True))


op.add_column(
        'bay',
        sa.Column('ca_cert_uuid', sa.String(length=36), nullable=True))
    op.add_column(
        'bay',
        sa.Column('magnum_cert_uuid', sa.String(length=36), nullable=True))

"""Add cert_uuuid to bay

Revision ID: 6f21dc920bb
Revises: 966a99e70ff
Create Date: 2015-08-19 13:57:14.863292

"""

# revision identifiers, used by Alembic.
revision = '6f21dc920bb'
down_revision = '966a99e70ff'

from alembic import op  # noqa: E402
import sqlalchemy as sa  # noqa: E402

def upgrade():


"""Add cert_uuuid to bay

Revision ID: 6f21dc920bb
Revises: 966a99e70ff
Cr

eate Date: 2015-08-19 13:57:14.863292

"""

# revision identifiers, used by Alembic.
revision = '6f21dc920bb'
down_revision = '966a99e70ff'

from alembic import op  # noqa: E402
import sqlalchemy as sa  # noqa: E402

def upgrade():
    op.add_column(
        'bay',
        sa.Column('ca_cert_uuid', sa.String(length=36), nullable=True))
    op.add_column(
        'bay',
        sa.Column('magnum_cert_uuid', sa.String(length=36), nullable=True))


def get_message_thread_link(self, chat_id: int, message_id: int) -> str:

"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """
        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'
        return self.CHAT_LINK

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """
        return f'{self.get_chat_link(chat_id)}/{message_id}'

"""
        We try to generate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


"""
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """
        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'
        return self.CHAT_LINK

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """
        return f'{self.get_chat_link(chat_id)}/{message_id}'

    def get_message_thread_link(self, chat_id: int, message_id: int) -> str:
        """
        We try to generate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


"""
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """

"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:

        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'
        return self.CHAT_LINK

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """
        return f'{self.get_chat_link(chat_id)}/{message_id}'

    def get_message_thread_link(self, chat_id: int, message_id: int) -> str:
        """
        We try to generate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'

"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """

        return self.CHAT_LINK

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """
        return f'{self.get_chat_link(chat_id)}/{message_id}'

    def get_message_thread_link(self, chat_id: int, message_id: int) -> str:
        """
        We try to generate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """
        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """
        return f'{self.get_chat_link(chat_id)}/{message_id}'

    def get_message_thread_link(self, chat_id: int, message_id: int) -> str:
        """
        We try to generate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot =

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """
        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'
        return self.CHAT_LINK

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """
        return f'{self.get_chat_link(chat_id)}/{message_id}'

    def get_message_thread_link(self, chat_id: int, message_id: int) -> str:
        """
        We try to generate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """
        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'
        return self.CHAT_LINK

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """

    def get_message_thread_link(self, chat_id: int, message_id: int) -> str:
        """
        We try to generate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'

"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """
        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)


"""
Focus on making URLs
"""
from telebot import TeleBot

class URIfy(object):
    """
    We try to create URIs (maybe URLs, i don't really care, call whatever you want)
    """
    BASE_URL = "https://t.me"
    CHAT_ID = None
    CHAT_USERNAME = None
    CHAT_LINK = None

    def __init__(self, bot: TeleBot):
        self.bot = bot

    def get_chat_username(self, chat_id: int) -> str:
        """
        We only update username if chat id is different, otherwise we return cached username
        :param chat_id: ID of target chat
        :return: URL
        """
        if self.CHAT_ID != chat_id:
            self.CHAT_ID = chat_id
            chat_info = self.bot.get_chat(chat_id)
            if chat_info.username:
                self.CHAT_USERNAME = chat_info.username
            else:
                self.CHAT_USERNAME = chat_id
        return self.CHAT_USERNAME

    def get_chat_link(self, chat_id: int) -> str:
        """
        To generate chat link. We use caching here too: generate new link as long as the chat id is new.
        :param chat_id: ID of target chat
        :return: URL
        """
        if chat_id != self.CHAT_ID:
            self.CHAT_USERNAME = self.get_chat_username(chat_id)
            if isinstance(self.CHAT_USERNAME, int):
                if self.CHAT_USERNAME < 0:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{str(self.CHAT_USERNAME)[4:]}'
                else:
                    self.CHAT_LINK = f'{self.BASE_URL}/c/{self.CHAT_USERNAME}'
            else:
                self.CHAT_LINK = f'{self.BASE_URL}/{self.CHAT_USERNAME}'
        return self.CHAT_LINK

    def get_message_link(self, chat_id: int, message_id: int) -> str:
        """
        Make URL for message
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL to message in chat
        """
        return f'{self.get_chat_link(chat_id)}/{message_id}'

    def get_message_thread_link(self, chat_id: int, message_id: int) -> str:
        """
        We try to gen

erate a link to open thread view of a single message.
        Thread view shows all replies to a message with a fancy design.
        Template: msg_link?thread=msg_id
        :param chat_id: ID of target chat
        :param message_id: ID of target message
        :return: URL
        """
        return f"{self.get_message_link(chat_id, message_id)}?thread={message_id}"


#    OpenERP, Open Source Management Solution
{
    'name': 'Add XLS export to accounting reports',
    'version': '0.4.2',
    'license': 'AGPL-3',
    'author': 'Noviat',
    'category': 'Generic Modules/Accounting',
    'description': """

    This module adds XLS export to the following accounting reports:
        - general ledger
        - trial balance
        - partner ledger
        - partner balance
        - open invoices

    """,
    'depends': ['report_xls', 'account_financial_report_webkit'],
    'demo': [],
    'data': [
        'wizard/general_ledger_wizard_view.xml',
        'wizard/trial_balance_wizard_view.xml',
        'wizard/partners_ledger_wizard_view.xml',
        'wizard/partners_balance_wizard_view.xml',
        'wizard/open_in

voices_wizard_view.xml',
    ],
    'active': False,
    'installable': True,
}


from django.db import models
from django_th.models.services import Services

class Wallabag(Services):
    """

        wallabag model to be adapted for the new service
        to store url in your account

    """
    url = models.URLField(max_length=255)
    title = models.CharField(max_length=80, blank=True)
    tag = models.CharField(max_length=80, blank=True)
    trigger = models.ForeignKey('TriggerService')

    class Meta:
        app_label = 'django_th'
        db_table = 'django_th_wallabag'

"""

        :return: string representing object
        """
        return "My Wallabag %s" % self.url

    def __str__(self):
        return "%s" % self.url


from django.db import models
from django_th.models.services import Services

class Wallabag(Services):
    """

        wallabag model to be adapted for the new service
        to store url in your account

    """
    url = models.URLField(max_length=255)
    title = models.CharField(max_length=80, blank=True)
    tag = models.CharField(max_length=80, blank=True)
    trigger = models.ForeignKey('TriggerService')

    class Meta:
        app_label = 'django_th'
        db_table = 'django_th_wallabag'

    def show(self):
        """

        :return: string representing object
        """
        return "My Wallabag %s" % self.url

    def __str__(self):


from django.db import models
from django_th.models.services import Services

class Wallabag(Services):
    """

        wallabag model to be adapted for the new service
        to store url in your account

    """
    url = models.URLField(max_length=255)
    title = models.CharField(max_length=80, blank=True)
    tag = models.CharField(max_length=80, blank=True)
    trigger = models.ForeignKey('TriggerService')

    class Meta:
        app_label = 'django_th'
        db_table = 'django_th_wallabag'

    def show(self):
        """

        :return: string representing object
        """
        return "My Wallabag %s" % self.url

    def __str__(self):
        return "%s" % sel


from django.db import models
from django_th.models.services import Services

class Wallabag(Services):
    """

        wallabag model to be adapted for the new service
        to store url in your account

    """
    url = models.URLField(max_length=255)
    title = models.CharField(max_length=80, blank=True)
    tag = models.CharField(max_length=80, blank=True)
    trigger = models.ForeignKey('TriggerService')

    class Meta:
        app_label = 'django_th'
        db_table = 'django_th_wallabag'

    def show(self):
        """

        :return: string representing object
        """

    def __str__(self):
        return "%s" % self.url


django_th.models.services import Services

class Wallabag(Services):
    """

        wallabag model to be adapted for the new service
        to store url in your account

    """
    url = models.URLField(max_length=255)
    title = models.CharField(max_length=80, blank=True)
    tag = models.CharField(max_length=80, blank=True)
    trigger = models.ForeignKey('TriggerService')

    class Meta:
        app_label = 'django_th'
        db_table = 'django_th_wallabag'

    def show(self):
        """

        :return: string representing object
        """
        return "My Wallabag %s" % self.url

    def __str__(self):
        return "%s" % self.url


from yookassa.domain.common.confirmation_type import ConfirmationType
from yookassa.domain.common.data_context import DataContext
from yookassa.domain.models.confirmation.request.confirmation_embedded import \
    ConfirmationEmbedded as RequestConfirmationEmbedded
from yookassa.domain.models.confirmation.request.confirmation_external import \
    ConfirmationExternal as RequestConfirmationExternal
from yookassa.domain.models.confirmation.request.confirmation_qr import \
    ConfirmationQr as RequestConfirmationQr
from yookassa.domain.models.confirmation.request.confirmation_redirect import \
    ConfirmationRedirect as RequestConfirmationRedirect
from yookassa.domain.models.confirmation.request.confirmation_mobile_application import \
    ConfirmationMobileApplication as RequestConfirmationMobileApplication
from yookassa.domain.models.confirmation.response.confirmation_embedded import \
    ConfirmationEmbedded as ResponseConfirmationEmbedded
from yookassa.domain.models.confirmation.response.confirmation_external import \
    ConfirmationExternal as ResponseConfirmationExternal
from yookassa.domain.models.confirmation.response.confirmation_qr import \
    ConfirmationQr as ResponseConfirmationQr
from yookassa.domain.models.confirmation.response.confirmation_redirect import \
    ConfirmationRedirect as ResponseConfirmationRedirect
from yookassa.domain.models.confirmation.response.confirmation_mobile_application import \
    ConfirmationMobileApplication as ResponseConfirmationMobileApplication

class ConfirmationClassMap(DataContext):
    def __init__(self):
        super(ConfirmationClassMap, self).__init__(('request', 'response'))

    @property
    def request(self):
        return {
            ConfirmationType.REDIRECT: RequestConfirmationRedirect,
            ConfirmationType.EXTERNAL: RequestConfirmationExternal,
            ConfirmationType.EMBEDDED: RequestConfirmationEmbedded,
            ConfirmationType.QR: RequestConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: RequestConfirmationMobileApplication
        }

    @property

return {
            ConfirmationType.REDIRECT: ResponseConfirmationRedirect,
            ConfirmationType.EXTERNAL: ResponseConfirmationExternal,
            ConfirmationType.EMBEDDED: ResponseConfirmationEmbedded,
            ConfirmationType.QR: ResponseConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: ResponseConfirmationMobileApplication
        }


return {
            ConfirmationType.REDIRECT: RequestConfirmationRedirect,
            ConfirmationType.EXTERNAL: RequestConfirmationExternal,
            ConfirmationType.EMBEDDED: RequestConfirmationEmbedded,
            ConfirmationType.QR: RequestConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: RequestConfirmationMobileApplication
        }

from yookassa.domain.common.confirmation_type import ConfirmationType
from yookassa.domain.common.data_context import DataContext
from yookassa.domain.models.confirmation.request.confirmation_embedded import \
    ConfirmationEmbedded as RequestConfirmationEmbedded
from yookassa.domain.models.confirmation.request.confirmation_external import \
    ConfirmationExternal as RequestConfirmationExternal
from yookassa.domain.models.confirmation.request.confirmation_qr import \
    ConfirmationQr as RequestConfirmationQr
from yookassa.domain.models.confirmation.request.confirmation_redirect import \
    ConfirmationRedirect as RequestConfirmationRedirect
from yookassa.domain.models.confirmation.request.confirmation_mobile_application import \
    ConfirmationMobileApplication as RequestConfirmationMobileApplication
from yookassa.domain.models.confirmation.response.confirmation_embedded import \
    ConfirmationEmbedded as ResponseConfirmationEmbedded
from yookassa.domain.models.confirmation.response.confirmation_external import \
    ConfirmationExternal as ResponseConfirmationExternal
from yookassa.domain.models.confirmation.response.confirmation_qr import \
    ConfirmationQr as ResponseConfirmationQr
from yookassa.domain.models.confirmation.response.confirmation_redirect import \
    ConfirmationRedirect as ResponseConfirmationRedirect
from yookassa.domain.models.confirmation.response.confirmation_mobile_application import \
    ConfirmationMobileApplication as ResponseConfirmationMobileApplication

class ConfirmationClassMap(DataContext):
    def __init__(self):
        super(ConfirmationClassMap, self).__init__(('request', 'response'))

    @property
    def request(self):

    @property
    def response(self):
        return {
            ConfirmationType.REDIRECT: ResponseConfirmationRedirect,
            ConfirmationType.EXTERNAL: ResponseConfirmationExternal,
            ConfirmationType.EMBEDDED: ResponseConfirmationEmbedded,
            ConfirmationType.QR: ResponseConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: ResponseConfirmationMobileApplication
        }


from yookassa.domain.common.confirmation_type import ConfirmationType
from yookassa.domain.common.data_context import DataContext
from yookassa.domain.models.confirmation.request.confirmation_embedded import \
    ConfirmationEmbedded as RequestConfirmationEmbedded
from yookassa.domain.models.confirmation.request.confirmation_external import \
    ConfirmationExternal as RequestConfirmationExternal
from yookassa.domain.models.confirmation.request.confirmation_qr import \
    ConfirmationQr as RequestConfirmationQr
from yookassa.domain.models.confirmation.request.confirmation_redirect import \
    ConfirmationRedirect as RequestConfirmationRedirect
from yookassa.domain.models.confirmation.request.confirmation_mobile_application import \
    ConfirmationMobileApplication as RequestConfirmationMobileApplication
from yookassa.domain.models.confirmation.response.confirmation_embedded import \
    ConfirmationEmbedded as ResponseConfirmationEmbedded
from yookassa.domain.models.confirmation.response.confirmation_external import \
    ConfirmationExternal as ResponseConfirmationExternal
from yookassa.domain.models.confirmation.response.confirmation_qr import \
    ConfirmationQr as ResponseConfirmationQr
from yookassa.domain.models.confirmation.response.confirmation_redirect import \
    ConfirmationRedirect as ResponseConfirmationRedirect
from yookassa.domain.models.confirmation.response.confirmation_mobile_application import \
    ConfirmationMobileApplication as ResponseConfirmationMobileApplication

class ConfirmationClassMap(DataContext):
    def __init__(self):
        super(ConfirmationClassMap, self).__init__(('request', '

    @property
    def request(self):
        return {
            ConfirmationType.REDIRECT: RequestConfirmationRedirect,
            ConfirmationType.EXTERNAL: RequestConfirmationExternal,
            ConfirmationType.EMBEDDED: RequestConfirmationEmbedded,
            ConfirmationType.QR: RequestConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: RequestConfirmationMobileApplication
        }

    @property
    def response(self):
        return {
            ConfirmationType.REDIRECT: ResponseConfirmationRedirect,
            ConfirmationType.EXTERNAL: ResponseConfirmationExternal,
            ConfirmationType.EMBEDDED: ResponseConfirmationEmbedded,
            ConfirmationType.QR: ResponseConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: ResponseConfirmationMobileApplication
        }


from yookassa.domain.common.confirmation_type import ConfirmationType
from yookassa.domain.common.data_context import DataContext
from yookassa.domain.models.confirmation.request.confirmation_embedded import \
    ConfirmationEmbedded as RequestConfirmationEmbedded
from yookassa.domain.models.confirmation.request.confirmation_external import \
    ConfirmationExternal as RequestConfirmationExternal
from yookassa.domain.models.confirmation.request.confirmation_qr import \
    ConfirmationQr as RequestConfirmationQr
from yookassa.domain.models.confirmation.request.confirmation_redirect import

\
    ConfirmationRedirect as RequestConfirmationRedirect
from yookassa.domain.models.confirmation.request.confirmation_mobile_application import \
    ConfirmationMobileApplication as RequestConfirmationMobileApplication
from yookassa.domain.models.confirmation.response.confirmation_embedded import \
    ConfirmationEmbedded as ResponseConfirmationEmbedded
from yookassa.domain.models.confirmation.response.confirmation_external import \
    ConfirmationExternal as ResponseConfirmationExternal
from yookassa.domain.models.confirmation.response.confirmation_qr import \
    ConfirmationQr as ResponseConfirmationQr
from yookassa.domain.models.confirmation.response.confirmation_redirect import \
    ConfirmationRedirect as ResponseConfirmationRedirect
from yookassa.domain.models.confirmation.response.confirmation_mobile_application import \
    ConfirmationMobileApplication as ResponseConfirmationMobileApplication

class ConfirmationClassMap(DataContext):
    def __init__(self):
        super(ConfirmationClassMap, self).__init__(('request', 'response'))

    @property
    def request(self):
        return {
            ConfirmationType.REDIRECT: RequestConfirmationRedirect,
            ConfirmationType.EXTERNAL: RequestConfirmationExternal,
            ConfirmationType.EMBEDDED: RequestConfirmationEmbedded,
            ConfirmationType.QR: RequestConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: RequestConfirmationMobileApplication
        }

    @property
    def response(self):
        return {
            ConfirmationType.REDIRECT: ResponseConfirmationRedirect,
            ConfirmationType.EXTERNAL: ResponseConfirmationExternal,
            ConfirmationType.EMBEDDED: ResponseConfirmationEmbedded,
            ConfirmationType.QR: ResponseConfirmationQr,
            ConfirmationType.MOBILE_APPLICATION: ResponseConfirmationMobileApplication
        }


if missing_dependencies:
    raise ImportError(
        "Missing required dependencies {0}".format(missing_dependencies))

# pylint: disable-msg=W0614,W0401,W0611,W0622

# flake8: noqa

__docformat__ = 'restructuredtext'

# Let users know if they're missing any of our hard dependencies
hard_dependencies = ("numpy", "pytz", "dateutil")
missing_dependencies = []

for dependency in hard_dependencies:
    try:
        __import__(dependency)
    except ImportError as e:
        missing_dependencies.append(dependency)

del hard_dependencies, dependency, missing_dependencies

# numpy compat
from pandas.compat.numpy import *

try:
    from pandas._libs import (hashtable as _hashtable,
                             lib as _lib,
                             tslib as _tslib)
except ImportError as e:  # pragma: no cover
    # hack but overkill to use re
    module = str(e).replace('cannot import name ', '')
    raise ImportError("C extension: {0} not built. If you want to import "
                      "pandas from the source directory, you may need to run "
                      "'python setup.py build_ext --inplace --force' to build "
                      "the C extensions first.".format(module))

from datetime import datetime

# let init-time option registration happen
import pandas.core.config_init

from pandas.core.api import *
from pandas.core.sparse.api import *
from pandas.tseries.api import *
from pandas.core.computation.api import *
from pandas.core.reshape.api import *

from pandas.util._print_versions import show_versions
from pandas.io.api import *
from pandas.util._tester import test
import pandas.testing
import pandas.arrays

# use the closest tagged version if possible
from ._version import get_versions
v = get_versions()
__version__ = v.get('closest-tag', v['version'])
__git_version__ = v.get('full-revisionid')
del get_versions, v

# module level doc-string
__doc__ = """
pandas - a powerful data analysis and manipulation library for Python
=====================================================================

**pandas** is a Python package providing fast, flexible, and expressive data
structures designed to make working with "relational" or "labeled" data both
easy and intuitive. It aims to be the fundamental high-level building block for
doing practical, **real world** data analysis in Python. Additionally, it has
the broader goal of becoming **the most powerful and flexible open source data
analysis / manipulation tool available in any language**. It is already well on
its way toward this goal.

Main Features
-------------
Here are just a few of the things that pandas does well:

  - Easy handling of missing data in floating point as well as non-floating
    point data.
  - Size mutability: columns can be inserted and deleted from DataFrame and
    higher dimensional objects
  - Automatic and explicit data alignment: objects can be explicitly aligned
    to a set of labels, or the user can simply ignore the labels and let
    `Series`, `DataFrame`, etc. automatically align the data for you in
    computations.
  - Powerful, flexible group by functionality to perform split-apply-combine
    operations on data sets, for both aggregating and transforming data.
  - Make it easy to convert ragged, differently-indexed data in other Python
    and NumPy data structures into DataFrame objects.
  - Intelligent label-based slicing, fancy indexing, and subsetting of large
    data sets.
  - Intuitive merging and joining data sets.
  - Flexible reshaping and pivoting of data sets.
  - Hierarchical labeling of axes (possible to have multiple labels per tick).
  - Robust IO tools for loading data from flat files (CSV and delimited),
    Excel files, databases, and saving/loading data from the ultrafast HDF5
    format.
  - Time series-specific functionality: date range generation and frequency
    conversion, moving window statistics, moving window linear regressions,
    date shifting and lagging, etc.
"""