# Path: mothership/models.py
# def init_db():
# 	def process_bind_param(self, value, dialect):
# 	def process_result_value(self, value, dialect):
# 	def get(cls, **kwargs):
# 	def all(cls, **kwargs):
# 	def create(cls, **kwargs):
# 	def put(self):
# 	def delete(self):
# 	def commit():
# 	def update(self, **kwargs):
# 	def update_all(cls, **kwargs):
# 	def to_dict(self):
# 	def children(self):
# 	def __init__(self, name):
# 	def started(self):
# 	def active_fuzzers(self):
# 	def master_fuzzer(self):
# 	def num_executions(self):
# 	def num_crashes(self):
# 	def bitmap_cvg(self):
# 	def name(self):
# 	def campaign(self):
# 	def started(self):
# 	def running(self):
# class JsonType(types.TypeDecorator):
# class Model:
# class Campaign(Model, db.Model):
# class FuzzerInstance(Model, db.Model):
# class FuzzerSnapshot(Model, db.Model):
# class Crash(Model, db.Model):


import datetime
from collections import defaultdict
from itertools import tee
from math import ceil
from operator import itemgetter
from statistics import mean
from flask import Blueprint, jsonify, request, render_template
from sqlalchemy import desc
from sqlalchemy.orm.attributes import InstrumentedAttribute
from mothership import models
from sqlalchemy import func
graphs = Blueprint('graphs', __name__)

def get_starts(fuzzers):
	"""
	Compute the list of start times for a list of fuzzers so that the series of

	fuzzers[n].snapshots[0...m].unix_time - get_starts(fuzzers)[n]

	does not include gaps when no fuzzers where running

	:param fuzzers: the list of fuzzers to compute the start times for
	:return: the list of start values
	"""
	run_times = [(f.start_time, f.last_update) for f in fuzzers]
	start, stop = run_times[0]
	starts = []
	for run_time, fuzzer in zip(run_times, fuzzers):
		n_start, n_stop = run_time
		if n_start > stop:
			start += n_start - stop
		stop = n_stop
		starts.append(start)
	return starts

def get_activity_periods(instances):
	r = []
	start = 0
	running = 0
	duration = 0
	startstop_events = sorted(

# Path: mothership/models.py
# def init_db():
# 	def process_bind_param(self, value, dialect):
# 	def process_result_value(self, value, dialect):
# 	def get(cls, **kwargs):
# 	def all(cls, **kwargs):
# 	def create(cls, **kwargs):
# 	def put(self):
# 	def delete(self):
# 	def commit():
# 	def update(self, **kwargs):
# 	def update_all(cls, **kwargs):
# 	def to_dict(self):
# 	def children(self):
# 	def __init__(self, name):
# 	def started(self):
# 	def active_fuzzers(self):
# 	def master_fuzzer(self):
# 	def num_executions(self):
# 	def num_crashes(self):
# 	def bitmap_cvg(self):
# 	def name(self):
# 	def campaign(self):
# 	def started(self):
# 	def running(self):
# class JsonType(types.TypeDecorator):
# class Model:
# class Campaign(Model, db.Model):
# class FuzzerInstance(Model, db.Model):
# class FuzzerSnapshot(Model, db.Model):
# class Crash(Model, db.Model):


# Path: mothership/controllers/graphs.py
import datetime
from collections import defaultdict
from itertools import tee
from math import ceil
from operator import itemgetter
from statistics import mean
from flask import Blueprint, jsonify, request, render_template
from sqlalchemy import desc
from sqlalchemy.orm.attributes import InstrumentedAttribute
from mothership import models
from sqlalchemy import func

graphs = Blueprint('graphs', __name__)

def get_starts(fuzzers):
	"""
	Compute the list of start times for a list of fuzzers so that the series of

	fuzzers[n].snapshots[0...m].unix_time - get_starts(fuzzers)[n]

	does not include gaps when no fuzzers where running

	:param fuzzers: the list of fuzzers to compute the start times for
	:return: the list of start values
	"""
	run_times = [(f.start_time, f.last_update) for f in fuzzers]
	start, stop = run_times[0]
	starts = []
	for run_time, fuzzer in zip(run_times, fuzzers):
		n_start, n_stop = run_time
		if n_start > stop:
			start += n_start - stop
		stop = n_stop
		starts.append(start)
	return starts

def get_activity_periods(instances):
	r = []
	start = 0
	running = 0
	duration = 0
	startstop_events = sorted(

		[(i, i.snapshots.order_by(models.FuzzerSnapshot.unix_time).first().unix_time, True) for i in instances] +