Full Code of datascopeanalytics/traces for AI

main 8c8bde56379e cached
129 files
15.8 MB
4.1M tokens
421 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (16,557K chars total). Download the full file to get everything.
Repository: datascopeanalytics/traces
Branch: main
Commit: 8c8bde56379e
Files: 129
Total size: 15.8 MB

Directory structure:
gitextract_u5aix2x9/

├── .check_external_deps.sh
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── actions/
│   │   ├── setup-poetry-env/
│   │   │   └── action.yml
│   │   └── setup-poetry-env-only-main/
│   │       └── action.yml
│   └── workflows/
│       ├── main.yml
│       ├── on-release-main.yml
│       └── validate-codecov-config.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .readthedocs.yaml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── codecov.yaml
├── docs/
│   ├── Makefile
│   ├── _templates/
│   │   └── side-primary.html
│   ├── _themes/
│   │   ├── LICENSE
│   │   └── ms/
│   │       ├── layout.html
│   │       ├── relations.html
│   │       ├── static/
│   │       │   ├── flasky.css_t
│   │       │   └── small_flask.css
│   │       └── theme.conf
│   ├── api_reference.rst
│   ├── conf.py
│   ├── examples.rst
│   ├── goals.rst
│   ├── index.rst
│   ├── merge_strategies.rst
│   ├── sorted_dict.rst
│   └── unevenly-spaced.rst
├── docs-md/
│   ├── index.md
│   ├── modules.md
│   └── stylesheets/
│       └── extra.css
├── examples/
│   ├── Plot.ipynb
│   ├── Shaded.ipynb
│   ├── Untitled.ipynb
│   ├── data/
│   │   ├── lightbulb-01.csv
│   │   ├── lightbulb-02.csv
│   │   ├── lightbulb-03.csv
│   │   ├── lightbulb-04.csv
│   │   ├── lightbulb-05.csv
│   │   ├── lightbulb-06.csv
│   │   ├── lightbulb-07.csv
│   │   ├── lightbulb-08.csv
│   │   ├── lightbulb-09.csv
│   │   ├── lightbulb-10.csv
│   │   ├── lightbulb-11.csv
│   │   ├── lightbulb-12.csv
│   │   ├── lightbulb-13.csv
│   │   ├── lightbulb-14.csv
│   │   ├── lightbulb-15.csv
│   │   ├── lightbulb-16.csv
│   │   ├── lightbulb-17.csv
│   │   ├── lightbulb-18.csv
│   │   ├── lightbulb-19.csv
│   │   ├── lightbulb-20.csv
│   │   ├── lightbulb-21.csv
│   │   ├── lightbulb-22.csv
│   │   ├── lightbulb-23.csv
│   │   ├── lightbulb-24.csv
│   │   ├── lightbulb-25.csv
│   │   ├── lightbulb-26.csv
│   │   ├── lightbulb-27.csv
│   │   ├── lightbulb-28.csv
│   │   ├── lightbulb-29.csv
│   │   ├── lightbulb-30.csv
│   │   ├── lightbulb-31.csv
│   │   ├── lightbulb-32.csv
│   │   ├── lightbulb-33.csv
│   │   ├── lightbulb-34.csv
│   │   ├── lightbulb-35.csv
│   │   ├── lightbulb-36.csv
│   │   ├── lightbulb-37.csv
│   │   ├── lightbulb-38.csv
│   │   ├── lightbulb-39.csv
│   │   └── lightbulb-40.csv
│   ├── event_analysis.py
│   ├── financial_analysis.py
│   ├── helloworld.py
│   ├── iot_sensor_analysis.py
│   ├── stackystack.py
│   ├── stackystack.py.bak
│   └── timing.py
├── experiments/
│   ├── bench_merge.py
│   ├── bench_merge_strategies.py
│   ├── bench_sorted_dict.py
│   ├── bench_tickets.py
│   └── sorted_dict_replacement.py
├── mkdocs.yml
├── poetry.toml
├── pyproject.toml
├── tests/
│   ├── .coveragerc
│   ├── __init__.py
│   ├── test_compact.py
│   ├── test_distribution.py
│   ├── test_distribution_external.py
│   ├── test_docs.py
│   ├── test_eventseries.py
│   ├── test_eventseries_external.py
│   ├── test_histogram.py
│   ├── test_histogram_external.py
│   ├── test_improved_methods.py
│   ├── test_iterators.py
│   ├── test_json_io.py
│   ├── test_methods.py
│   ├── test_methods_external.py
│   ├── test_missing.py
│   ├── test_operations.py
│   ├── test_plot.py
│   ├── test_plot_external.py
│   ├── test_something.py
│   ├── test_sorted_dict.py
│   ├── test_traces.py
│   ├── test_traces_external.py
│   └── test_utils.py
├── tox.ini
└── traces/
    ├── __init__.py
    ├── decorators.py
    ├── eventseries.py
    ├── histogram.py
    ├── infinity.py
    ├── operations.py
    ├── plot.py
    ├── sorted_dict.py
    ├── timeseries.py
    └── utils.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .check_external_deps.sh
================================================
#!/bin/sh

# write all imports that are in non-external-named test files
grep "import " tests/*.py | grep -v "external" > .test_external_deps_imports
# ls tests/*.py | grep -v external | xargs cat | grep "import " | sort | uniq > .test_external_deps_imports

# # go through every value in this and grep
> .test_external_deps_overlap
for i in `poetry show -T --only dev | tr '-' '_' | awk '{print $1}'`; do
    grep $i .test_external_deps_imports >> .test_external_deps_overlap
done;

cat .test_external_deps_overlap | grep -v "\bpytest\b" | sort | uniq
rm -f .test_external_deps_imports .test_external_deps_overlap


================================================
FILE: .editorconfig
================================================
max_line_length = 80

[*.json]
indent_style = space
indent_size = 2


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
- Simplicity is better than functionality
- The API matters most, everything else is secondary

For feature requests, please include a description of why the feature
will be useful to most users.


================================================
FILE: .github/actions/setup-poetry-env/action.yml
================================================
name: "setup-poetry-env"
description: "Composite action to setup the Python and poetry environment."

inputs:
  python-version:
    required: false
    description: "The python version to use"
    default: "3.14"

runs:
  using: "composite"
  steps:
    - name: Set up python
      uses: actions/setup-python@v5
      with:
        python-version: ${{ inputs.python-version }}

    - name: Install Poetry
      uses: snok/install-poetry@v1
      with:
        virtualenvs-in-project: true

    - name: Install dependencies
      run: poetry install --no-interaction
      shell: bash


================================================
FILE: .github/actions/setup-poetry-env-only-main/action.yml
================================================
name: "setup-poetry-env"
description: "Composite action to setup the Python and poetry environment."

inputs:
  python-version:
    required: false
    description: "The python version to use"
    default: "3.14"

runs:
  using: "composite"
  steps:
    - name: Set up python
      uses: actions/setup-python@v5
      with:
        python-version: ${{ inputs.python-version }}

    - name: Install Poetry
      uses: snok/install-poetry@v1
      with:
        virtualenvs-in-project: true

    - name: Install dependencies
      run: poetry install --no-interaction --only main
      shell: bash


================================================
FILE: .github/workflows/main.yml
================================================
name: Main

on:
  push:
    branches:
      - main
      - dev
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v4

      - uses: actions/cache@v4
        with:
          path: ~/.cache/pre-commit
          key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}

      - name: Set up the environment
        uses: ./.github/actions/setup-poetry-env

      - name: Run checks
        run: make check

  tests-only-main-dependencies:
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v4

      - name: Set up the environment
        uses: ./.github/actions/setup-poetry-env-only-main

      - name: just add pytest for running tests
        run: poetry run python -m pip install -U pytest

      - name: run the tests that don't require development dependencies
        run: make test-only-main

  tox:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
      fail-fast: false
    steps:
      - name: Check out
        uses: actions/checkout@v4

      - name: Set up python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install Poetry
        uses: snok/install-poetry@v1

      - name: Load cached venv
        uses: actions/cache@v4
        with:
          path: .tox
          key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}

      - name: Install tox
        run: |
          python -m pip install --upgrade pip
          python -m pip install tox tox-gh-actions

      - name: Test with tox
        run: tox

      - name: Upload coverage reports to Codecov with GitHub Action on Python 3.14
        uses: codecov/codecov-action@v4
        if: ${{ matrix.python-version == '3.14' }}

  check-docs:
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v4

      - name: Set up the environment
        uses: ./.github/actions/setup-poetry-env

      - name: Check if documentation can be built
        # run: poetry run mkdocs build -s
        run: poetry run sphinx-build docs docs/_build/html


================================================
FILE: .github/workflows/on-release-main.yml
================================================
name: release-main

on:
  release:
    types: [published]
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v4

      - name: Set up the environment
        uses: ./.github/actions/setup-poetry-env

      - name: Export tag
        id: vars
        run: echo tag=${GITHUB_REF#refs/*/} >> $GITHUB_OUTPUT

      - name: Build and publish
        run: |
          source .venv/bin/activate
          poetry version $RELEASE_VERSION
          make build-and-publish
        env:
          POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
          PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
          RELEASE_VERSION: ${{ steps.vars.outputs.tag }}

  deploy-docs:
    needs: publish
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v4

      - name: Set up the environment
        uses: ./.github/actions/setup-poetry-env

      - name: Deploy documentation
        run: poetry run mkdocs gh-deploy --force


================================================
FILE: .github/workflows/validate-codecov-config.yml
================================================
name: validate-codecov-config

on:
  pull_request:
    paths: [codecov.yaml]
  push:
    branches: [main]

jobs:
  validate-codecov-config:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - name: Validate codecov configuration
        run: curl -sSL --fail-with-body --data-binary @codecov.yaml https://codecov.io/validate


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
.eggs

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
.eggs
cover

# Translations
*.mo
*.pot

# IPython stuff
.ipynb_checkpoints/

# mkdocs
docs/_build

# PyBuilder
target/
.vscode

docs/source

# From https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
#   For a library or package, you might want to ignore these files since the code is
#   intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# poetry
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
poetry.lock

# pdm
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
#   in version control.
#   https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# Vscode config files
.vscode/

# PyCharm
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/


================================================
FILE: .pre-commit-config.yaml
================================================
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: "v4.4.0"
    hooks:
      - id: check-case-conflict
      - id: check-merge-conflict
      - id: check-toml
      - id: check-yaml
      - id: end-of-file-fixer
      - id: trailing-whitespace

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: "v0.1.6"
    hooks:
      - id: ruff
        args: [--exit-non-zero-on-fix]
      - id: ruff-format

  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: "v3.0.3"
    hooks:
      - id: prettier


================================================
FILE: .readthedocs.yaml
================================================
version: 2

build:
  os: ubuntu-22.04
  tools:
    python: "3.12"
  jobs:
    post_install:
      - pip install poetry
      - poetry config virtualenvs.create false
      - poetry install --only main --only docs
    build:
      html:
        - python -m sphinx -T -b html -d docs/_build/doctrees -D language=en docs $READTHEDOCS_OUTPUT/html


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## [0.6.5] - In Development

### Added

- Added JSON import/export functionality:
  - `TimeSeries.from_json()` method to load from JSON files or strings
  - `TimeSeries.to_json()` method to export to JSON files or strings
  - Support for custom time and value transformations
  - Support for different JSON formats (list or dictionary)
- Added `is_not_none()` method as an improved replacement for the `exists()` method
- Added comprehensive docstrings for all public methods
- Added comprehensive documentation for `EventSeries` class
- Added three new advanced examples:
  - `financial_analysis.py`: Demonstrating financial time series use cases
  - `iot_sensor_analysis.py`: Demonstrating IoT sensor data analysis
  - `event_analysis.py`: Demonstrating EventSeries use cases
- Added deprecation warning to `exists()` method

### Fixed

- Fixed incorrect error handling in `_get_previous()` method
- Fixed string representation (`__str__` and `__repr__`) to consistently include default value
- Improved variable naming in string representation methods for clarity

## [0.6.4] - 2023-03-01

- Updating dependencies
- Fix vulnerability in dependencies


================================================
FILE: CONTRIBUTING.md
================================================
# Authors

Created by [Mike Stringer](https://github.com/stringertheory/), [Vlad Seghete](https://github.com/vlsd/), and [Yoke Peng Leong](https://github.com/ypleong/) while working at Datascope. [Mike](https://github.com/stringertheory/) is most recently maintaining traces.

With merged pull requests by [sdementen](https://github.com/sdementen), [nsteins](https://github.com/nsteins), [zzrcxb](https://github.com/zzrcxb), [gokturksm](https://github.com/gokturksm). Thank you!

# Design Philosophy

- "Simplicity is better than functionality." - Pieter Hintjens
- "The API matters most, everything else is secondary." - Kenneth
  Reitz

# Contributing to `traces`

Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. You can contribute in many ways.

# Types of Contributions

## Report Bugs

Report bugs at https://github.com/stringertheory/traces/issues

If you are reporting a bug, please include:

- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.

## Fix Bugs

Look through the GitHub issues for bugs. Anything tagged with "bug"
and "help wanted" is open to whoever wants to implement a fix for it.

## Implement Features

Look through the GitHub issues for features. Anything tagged with
"enhancement" and "help wanted" is open to whoever wants to implement
it.

## Write Documentation

Traces could always use more documentation, whether as part of the
official docs, in docstrings, or even on the web in blog posts,
articles, and such.

## Submit Feedback

The best way to send feedback is to file an issue at
https://github.com/stringertheory/traces/issues.

If you are proposing a new feature:

- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions
  are welcome :)

# Get Started!

Ready to contribute? Here's how to set up `traces` for local development.
Please note this documentation assumes you already have `poetry` and `Git` installed and ready to go.

1. Fork the `traces` repo on GitHub.

2. Clone your fork locally:

```bash
cd <directory_in_which_repo_should_be_created>
git clone git@github.com:YOUR_NAME/traces.git
```

3. Now we need to install the environment. Navigate into the directory

```bash
cd traces
```

If you are using `pyenv`, select a version to use locally. (See installed versions with `pyenv versions`)

```bash
pyenv local <x.y.z>
```

Then, install and activate the environment with:

```bash
poetry install
poetry shell
```

4. Install pre-commit to run linters/formatters at commit time:

```bash
poetry run pre-commit install
```

5. Create a branch for local development:

```bash
git checkout -b name-of-your-bugfix-or-feature
```

Now you can make your changes locally.

6. Don't forget to add test cases for your added functionality to the `tests` directory.

7. When you're done making changes, check that your changes pass the formatting tests.

```bash
make check
```

Now, validate that all unit tests are passing:

```bash
make test
```

9. Before raising a pull request you should also run tox.
   This will run the tests across different versions of Python:

```bash
tox
```

This requires you to have multiple versions of python installed.
This step is also triggered in the CI/CD pipeline, so you could also choose to skip this step locally.

10. Commit your changes and push your branch to GitHub:

```bash
git add .
git commit -m "Your detailed description of your changes."
git push origin name-of-your-bugfix-or-feature
```

11. Submit a pull request through the GitHub website.

# Pull Request Guidelines

Before you submit a pull request, check that it meets these guidelines:

1. The pull request should include tests.

2. If the pull request adds functionality, the docs should be updated.
   Put your new functionality into a function with a docstring, and add the feature to the list in `README.md`.


================================================
FILE: LICENSE
================================================

MIT License

Copyright (c) 2016, Mike Stringer

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: Makefile
================================================
.PHONY: install
install: ## Install the poetry environment and install the pre-commit hooks
	@echo "🚀 Creating virtual environment using pyenv and poetry"
	@poetry install
	@poetry run pre-commit install
	@poetry shell

.PHONY: check
check: ## Run code quality tools.
	@echo "🚀 Linting code: Running pre-commit"
	@poetry run pre-commit run -a
	# @echo "🚀 Static type checking: Running mypy"
	# @poetry run mypy
	# @echo "🚀 Checking for obsolete dependencies: Running deptry"
	# @poetry run deptry traces
	@echo "🚀 Check if using dev dependencies outside of tests marked external"
	@./.check_external_deps.sh

.PHONY: test
test: ## Test the code with pytest
	@echo "🚀 Testing code: Running pytest"
	@poetry run pytest --cov --cov-config=pyproject.toml --cov-report=xml

.PHONY: test-only-main
test-only-main: ## Test the code with pytest
	@echo "🚀 Testing code: Running pytest with only main dependencies"
	@poetry run pytest $$(ls tests/*.py | grep -v external)

.PHONY: build
build: clean-build ## Build wheel file using poetry
	@echo "🚀 Creating wheel file"
	@poetry build

.PHONY: clean-build
clean-build: ## clean build artifacts
	@rm -rf dist

.PHONY: publish
publish: ## publish a release to pypi.
	@echo "🚀 Publishing: Dry run."
	@poetry config pypi-token.pypi $(POETRY_PYPI_TOKEN_PYPI)
	@poetry publish --dry-run
	@echo "🚀 Publishing."
	@poetry publish

.PHONY: build-and-publish
build-and-publish: build publish ## Build and publish.

.PHONY: docs-test
docs-test: ## Test if documentation can be built without warnings or errors
	# @poetry run mkdocs build -s
	@poetry run sphinx-build docs docs/_build/html

.PHONY: docs
docs: ## Build and serve the documentation
	# @poetry run mkdocs serve -a localhost:8002
	@poetry run sphinx-autobuild --port 8002 docs docs/_build/html

.PHONY: help
help:
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

.DEFAULT_GOAL := help


================================================
FILE: README.md
================================================
<!-- [![Version](https://img.shields.io/pypi/v/traces.svg?)](https://pypi.python.org/pypi/traces) -->
<!-- [![PyVersions](https://img.shields.io/pypi/pyversions/traces.svg)](https://pypi.python.org/pypi/traces) -->
<!-- [![Documentation Status](https://readthedocs.org/projects/traces/badge/?version=master)](https://traces.readthedocs.io/en/master/?badge=master) -->
<!-- [![Release](https://img.shields.io/github/v/release/stringertheory/traces)](https://img.shields.io/github/v/release/stringertheory/traces) -->

[![Build status](https://img.shields.io/github/actions/workflow/status/stringertheory/traces/main.yml?branch=main)](https://github.com/stringertheory/traces/actions/workflows/main.yml?query=branch%3Amain)
[![codecov](https://codecov.io/gh/stringertheory/traces/branch/main/graph/badge.svg)](https://codecov.io/gh/stringertheory/traces)
[![Commit activity](https://img.shields.io/github/commit-activity/y/stringertheory/traces)](https://img.shields.io/github/commit-activity/m/stringertheory/traces)

# traces

A Python library for unevenly-spaced time series analysis.

## Why?

Taking measurements at irregular intervals is common, but most tools are
primarily designed for evenly-spaced measurements. Also, in the real
world, time series have missing observations or you may have multiple
series with different frequencies: it can be useful to model these as
unevenly-spaced.

Traces was designed by the team at
[Datascope](<[https://datascopeanalytics.com/](https://en.wikipedia.org/wiki/Datascope_Analytics)>) based on several practical
applications in different domains, because it turns out [unevenly-spaced
data is actually pretty great, particularly for sensor data
analysis](https://traces.readthedocs.io/).

## Installation

To install traces, run this command in your terminal:

```shell
$ pip install traces
```

## Quickstart: using traces

To see a basic use of traces, let's look at these data from a light
switch, also known as _Big Data from the Internet of Things_.

![](docs/_static/img/trace.svg)

The main object in traces is a [TimeSeries](https://traces.readthedocs.io/en/master/api_reference.html#timeseries), which you
create just like a dictionary, adding the five measurements at 6:00am,
7:45:56am, etc.

```pycon
>>> time_series = traces.TimeSeries()
>>> time_series[datetime(2042, 2, 1,  6,  0,  0)] = 0 #  6:00:00am
>>> time_series[datetime(2042, 2, 1,  7, 45, 56)] = 1 #  7:45:56am
>>> time_series[datetime(2042, 2, 1,  8, 51, 42)] = 0 #  8:51:42am
>>> time_series[datetime(2042, 2, 1, 12,  3, 56)] = 1 # 12:03:56am
>>> time_series[datetime(2042, 2, 1, 12,  7, 13)] = 0 # 12:07:13am
```

What if you want to know if the light was on at 11am? Unlike a python
dictionary, you can look up the value at any time even if it's not one
of the measurement times.

```pycon
>>> time_series[datetime(2042, 2, 1, 11,  0, 0)] # 11:00am
0
```

The `distribution` function gives you the fraction of time that the
`TimeSeries` is in each state.

```pycon
>>> time_series.distribution(
>>>   start=datetime(2042, 2, 1,  6,  0,  0), # 6:00am
>>>   end=datetime(2042, 2, 1,  13,  0,  0)   # 1:00pm
>>> )
Histogram({0: 0.8355952380952381, 1: 0.16440476190476191})
```

The light was on about 16% of the time between 6am and 1pm.

### Adding more data...

Now let's get a little more complicated and look at the sensor readings
from forty lights in a house.

![](docs/_static/img/traces.svg)

How many lights are on throughout the day? The merge function takes the
forty individual `TimeSeries` and efficiently merges them into one
`TimeSeries` where the each value is a list of all lights.

```pycon
>>> trace_list = [... list of forty traces.TimeSeries ...]
>>> count = traces.TimeSeries.merge(trace_list, operation=sum)
```

We also applied a `sum` operation to the list of states to get the
`TimeSeries` of the number of lights that are on.

![](docs/_static/img/count.svg)

How many lights are on in the building on average during business hours,
from 8am to 6pm?

```pycon
>>> histogram = count.distribution(
>>>   start=datetime(2042, 2, 1,  8,  0,  0),   # 8:00am
>>>   end=datetime(2042, 2, 1,  12 + 6,  0,  0) # 6:00pm
>>> )
>>> histogram.median()
17
```

The `distribution` function returns a [Histogram](https://traces.readthedocs.io/en/master/api_reference.html#histogram) that
can be used to get summary metrics such as the mean or quantiles.

### It's flexible

The measurements points (keys) in a `TimeSeries` can be in any units as
long as they can be ordered. The values can be anything.

For example, you can use a `TimeSeries` to keep track the contents of a
grocery basket by the number of minutes within a shopping trip.

```pycon
>>> time_series = traces.TimeSeries()
>>> time_series[1.2] = {'broccoli'}
>>> time_series[1.7] = {'broccoli', 'apple'}
>>> time_series[2.2] = {'apple'}          # puts broccoli back
>>> time_series[3.5] = {'apple', 'beets'} # mmm, beets
```

## More info

To learn more, check the [examples](https://traces.readthedocs.io/en/master/examples.html) and the detailed [reference](https://traces.readthedocs.io/en/master/api_reference.html#).

## Contributing

Contributions are welcome and greatly appreciated! Please visit our [guidelines](https://github.com/datascopeanalytics/traces/blob/master/CONTRIBUTING.md)
for more info.


================================================
FILE: codecov.yaml
================================================
coverage:
  range: 70..100
  round: down
  precision: 1
  status:
    project:
      default:
        target: 90%
        threshold: 0.5%


================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = _build

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .

.PHONY: help
help:
	@echo "Please use \`make <target>' where <target> is one of"
	@echo "  html       to make standalone HTML files"
	@echo "  dirhtml    to make HTML files named index.html in directories"
	@echo "  singlehtml to make a single large HTML file"
	@echo "  pickle     to make pickle files"
	@echo "  json       to make JSON files"
	@echo "  htmlhelp   to make HTML files and a HTML help project"
	@echo "  qthelp     to make HTML files and a qthelp project"
	@echo "  applehelp  to make an Apple Help Book"
	@echo "  devhelp    to make HTML files and a Devhelp project"
	@echo "  epub       to make an epub"
	@echo "  epub3      to make an epub3"
	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
	@echo "  text       to make text files"
	@echo "  man        to make manual pages"
	@echo "  texinfo    to make Texinfo files"
	@echo "  info       to make Texinfo files and run them through makeinfo"
	@echo "  gettext    to make PO message catalogs"
	@echo "  changes    to make an overview of all changed/added/deprecated items"
	@echo "  xml        to make Docutils-native XML files"
	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
	@echo "  linkcheck  to check all external links for integrity"
	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
	@echo "  coverage   to run coverage check of the documentation (if enabled)"
	@echo "  dummy      to check syntax errors of document sources"

.PHONY: clean
clean:
	rm -rf $(BUILDDIR)/*

.PHONY: html
html:
	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

.PHONY: dirhtml
dirhtml:
	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."

.PHONY: singlehtml
singlehtml:
	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
	@echo
	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."

.PHONY: pickle
pickle:
	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
	@echo
	@echo "Build finished; now you can process the pickle files."

.PHONY: json
json:
	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
	@echo
	@echo "Build finished; now you can process the JSON files."

.PHONY: htmlhelp
htmlhelp:
	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
	@echo
	@echo "Build finished; now you can run HTML Help Workshop with the" \
	      ".hhp project file in $(BUILDDIR)/htmlhelp."

.PHONY: qthelp
qthelp:
	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
	@echo
	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/traces.qhcp"
	@echo "To view the help file:"
	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/traces.qhc"

.PHONY: applehelp
applehelp:
	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
	@echo
	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
	@echo "N.B. You won't be able to view it unless you put it in" \
	      "~/Library/Documentation/Help or install it in your application" \
	      "bundle."

.PHONY: devhelp
devhelp:
	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
	@echo
	@echo "Build finished."
	@echo "To view the help file:"
	@echo "# mkdir -p $$HOME/.local/share/devhelp/traces"
	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/traces"
	@echo "# devhelp"

.PHONY: epub
epub:
	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
	@echo
	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."

.PHONY: epub3
epub3:
	$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
	@echo
	@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."

.PHONY: latex
latex:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo
	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
	@echo "Run \`make' in that directory to run these through (pdf)latex" \
	      "(use \`make latexpdf' here to do that automatically)."

.PHONY: latexpdf
latexpdf:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through pdflatex..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

.PHONY: latexpdfja
latexpdfja:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through platex and dvipdfmx..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

.PHONY: text
text:
	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
	@echo
	@echo "Build finished. The text files are in $(BUILDDIR)/text."

.PHONY: man
man:
	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
	@echo
	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

.PHONY: texinfo
texinfo:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo
	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
	@echo "Run \`make' in that directory to run these through makeinfo" \
	      "(use \`make info' here to do that automatically)."

.PHONY: info
info:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo "Running Texinfo files through makeinfo..."
	make -C $(BUILDDIR)/texinfo info
	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."

.PHONY: gettext
gettext:
	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
	@echo
	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."

.PHONY: changes
changes:
	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
	@echo
	@echo "The overview file is in $(BUILDDIR)/changes."

.PHONY: linkcheck
linkcheck:
	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
	@echo
	@echo "Link check complete; look for any errors in the above output " \
	      "or in $(BUILDDIR)/linkcheck/output.txt."

.PHONY: doctest
doctest:
	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
	@echo "Testing of doctests in the sources finished, look at the " \
	      "results in $(BUILDDIR)/doctest/output.txt."

.PHONY: coverage
coverage:
	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
	@echo "Testing of coverage in the sources finished, look at the " \
	      "results in $(BUILDDIR)/coverage/python.txt."

.PHONY: xml
xml:
	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
	@echo
	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."

.PHONY: pseudoxml
pseudoxml:
	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
	@echo
	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

.PHONY: dummy
dummy:
	$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
	@echo
	@echo "Build finished. Dummy builder generates no files."


================================================
FILE: docs/_templates/side-primary.html
================================================
<p class="logo">
  <a href="{{ pathto(master_doc) }}"
    ><img class="logo" src="{{ pathto('_static/img/logo.png', 1) }}" alt="Logo"
  /></a>
</p>

<p>
  <!-- <iframe src="https://ghbtns.com/github-btn.html?user=datascopeanalytics&repo=traces&type=watch&count=true&size=large"
         allowtransparency="true" frameborder="0" scrolling="0" width="200px" height="35px"></iframe> -->
</p>

<p>
  <span class="name">Traces</span> is a Python library for unevenly-spaced time
  series analysis.
</p>

<ul>
  <li>
    <a href="https://github.com/datascopeanalytics/traces">Traces on Github</a>
  </li>
  <li>
    <a
      href="https://github.com/datascopeanalytics/traces/blob/master/CHANGELOG.md"
      >Changelog</a
    >
  </li>
</ul>

<h3>{{ _('Table Of Contents') }}</h3>
{{ toctree(maxdepth=2, collapse=False, includehidden=True) }}

<h3>Versions</h3>
<ul>
  <li><a href="http://traces.readthedocs.io/en/master/">master</a></li>
  <li><a href="http://traces.readthedocs.io/en/latest/">latest</a></li>
  <li><a href="http://traces.readthedocs.io/en/master/">dev</a></li>
</ul>


================================================
FILE: docs/_themes/LICENSE
================================================
Modifications:

Copyright (c) 2010 Kenneth Reitz.
Copyright (c) 2016 Mike Stringer.


Original Project:

Copyright (c) 2010 by Armin Ronacher.


Some rights reserved.

Redistribution and use in source and binary forms of the theme, with or
without modification, are permitted provided that the following conditions
are met:

* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the following
  disclaimer in the documentation and/or other materials provided
  with the distribution.

* The names of the contributors may not be used to endorse or
  promote products derived from this software without specific
  prior written permission.

We kindly ask you to only use these themes in an unmodified manner just
for Flask and Flask-related products, not for unrelated projects.  If you
like the visual style and want to use it for your own projects, please
consider making some larger changes to the themes (such as changing
font faces, sizes, colors or margins).

THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: docs/_themes/ms/layout.html
================================================
{%- extends "basic/layout.html" %} {%- block extrahead %} {{ super() }} {% if
theme_touch_icon %}
<link
  rel="apple-touch-icon"
  href="{{ pathto('_static/' ~ theme_touch_icon, 1) }}"
/>
{% endif %}
<link
  href="https://fonts.googleapis.com/css?family=Rubik:400,400i,700"
  rel="stylesheet"
/>

<link
  media="only screen and (max-device-width: 480px)"
  href="{{
    pathto('_static/small_flask.css', 1) }}"
  type="text/css"
  rel="stylesheet"
/>
<meta
  name="viewport"
  content="width=device-width, initial-scale=0.9, maximum-scale=0.9"
/>
{% endblock %} {%- block relbar2 %}{% endblock %} {%- block footer %}
<div class="footer">&copy; {{ copyright }}</div>
{%- endblock %}


================================================
FILE: docs/_themes/ms/relations.html
================================================
<h3>Related Topics</h3>
<ul>
  <li>
    <a href="{{ pathto(master_doc) }}">Documentation overview</a>
    <ul>
      {%- for parent in parents %}
      <li>
        <a href="{{ parent.link|e }}">{{ parent.title }}</a>
        <ul>
          {%- endfor %} {%- if prev %}
          <li>
            Previous:
            <a
              href="{{ prev.link|e }}"
              title="{{ _('previous chapter')
        }}"
              >{{ prev.title }}</a
            >
          </li>
          {%- endif %} {%- if next %}
          <li>
            Next:
            <a
              href="{{ next.link|e }}"
              title="{{ _('next chapter')
        }}"
              >{{ next.title }}</a
            >
          </li>
          {%- endif %} {%- for parent in parents %}
        </ul>
      </li>
      {%- endfor %}
    </ul>
  </li>
</ul>


================================================
FILE: docs/_themes/ms/static/flasky.css_t
================================================
/*
 * flasky.css_t
 * ~~~~~~~~~~~~
 *
 * :copyright: Copyright 2010 by Armin Ronacher. Modifications by Kenneth Reitz.
 * :license: Flask Design License, see LICENSE for details.
 */

{% set page_width = '900px' %}
{% set sidebar_width = '220px' %}

@import url("basic.css");

/* -- page layout ----------------------------------------------------------- */

body {
    font-family: 'Rubik', sans-serif;
    font-size: 20px;
    background-color: white;
    color: #000;
    margin: 0;
    padding: 0;
}

#api-reference {
    font-size: 16px;
}
.name {
    font-weight: bold;
}

div.document {
    width: {{ page_width }};
    margin: 30px auto 0 auto;
}

div.documentwrapper {
    float: left;
    width: 100%;
}

div.bodywrapper {
    margin: 0 0 0 {{ sidebar_width }};
}

div.sphinxsidebar {
    width: {{ sidebar_width }};
}

hr {
    border: 1px solid #B1B4B6;
}

div.body {
    background-color: #ffffff;
    color: #3E4349;
    padding: 0 30px 0 30px;
}

img.floatingflask {
    padding: 0 0 10px 10px;
    float: right;
}

div.footer {
    width: {{ page_width }};
    margin: 20px auto 30px auto;
    font-size: 14px;
    color: #888;
    text-align: right;
}

div.footer a {
    color: #888;
}

div.related {
    display: none;
}

div.sphinxsidebar a {
    color: #444;
    text-decoration: none;
    border-bottom: 1px dotted #999;
}

div.sphinxsidebar a:hover {
    border-bottom: 1px solid #999;
}

div.sphinxsidebar {
    font-size: 14px;
    line-height: 1.5;
}

div.sphinxsidebarwrapper {
    padding-top: 0px;
    padding-bottom: 18px;
    padding-left: 10px;
    padding-right: 10px;
}

div.sphinxsidebarwrapper p.logo {
    padding: 0;
    margin-top: 0px;
    margin-bottom: 10px;
    margin-left: 0px;
    margin-top: 0px;
    text-align: center;
}

div.sphinxsidebar h3,
div.sphinxsidebar h4 {
    font-family: 'Rubik', sans-serif;
    color: #444;
    font-size: 24px;
    font-weight: normal;
    margin: 0 0 5px 0;
    padding: 0;
}

div.sphinxsidebar h4 {
    font-size: 20px;
}

div.sphinxsidebar h3 a {
    color: #444;
}

div.sphinxsidebar p.logo a,
div.sphinxsidebar h3 a,
div.sphinxsidebar p.logo a:hover,
div.sphinxsidebar h3 a:hover {
    border: none;
}

div.sphinxsidebar p {
    color: #555;
    margin: 10px 0;
}

div.sphinxsidebar ul {
    margin: 10px 0;
    padding: 0;
    color: #000;
}

div.sphinxsidebar input {
    border: 1px solid #ccc;
    font-family: 'Rubik', sans-serif;
    font-size: 1em;
}

/* -- body styles ----------------------------------------------------------- */

a {
    color: #004B6B;
    text-decoration: underline;
}

a:hover {
    color: #6D4100;
    text-decoration: underline;
}

div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
    font-family: 'Rubik', sans-serif;
    font-weight: bold;
    margin: 30px 0px 10px 0px;
    padding: 0;
}

div.body h1 { margin-top: 0; padding-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 130%; }
div.body h4 { font-size: 110%; }
div.body h5 { font-size: 100%; }
div.body h6 { font-size: 100%; }

a.headerlink {
    color: #ddd;
    padding: 0 4px;
    text-decoration: none;
}

a.headerlink:hover {
    color: #444;
    background: #eaeaea;
}

div.body p, div.body dd, div.body li {
    line-height: 1.4em;
}

div.admonition {
    background: #fafafa;
    margin: 20px -30px;
    padding: 10px 30px;
    border-top: 1px solid #ccc;
    border-bottom: 1px solid #ccc;
}

div.admonition tt.xref, div.admonition a tt {
    border-bottom: 1px solid #fafafa;
}

dd div.admonition {
    margin-left: -60px;
    padding-left: 60px;
}

div.admonition p.admonition-title {
    font-family: 'Rubik', sans-serif;
    font-weight: normal;
    font-size: 24px;
    margin: 0 0 10px 0;
    padding: 0;
    line-height: 1;
}

div.admonition p.last {
    margin-bottom: 0;
}

div.highlight {
    background-color: white;
}

dt:target, .highlight {
    background: #FAF3E8;
}

div.note {
    background-color: #eee;
    border: 1px solid #ccc;
}

div.seealso {
    background-color: #ffc;
    border: 1px solid #ff6;
}

div.topic {
    background-color: #eee;
}

p.admonition-title {
    display: inline;
}

p.admonition-title:after {
    content: ":";
}

pre, tt {
    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
    font-size: 14px;
}

.highlight .go {
    color: #888 !important;
}

img.screenshot {
}

tt.descname, tt.descclassname {
    font-size: 0.95em;
}

tt.descname {
    padding-right: 0.08em;
}

img.screenshot {
    -moz-box-shadow: 2px 2px 4px #eee;
    -webkit-box-shadow: 2px 2px 4px #eee;
    box-shadow: 2px 2px 4px #eee;
}

table.docutils {
    border: 1px solid #888;
    -moz-box-shadow: 2px 2px 4px #eee;
    -webkit-box-shadow: 2px 2px 4px #eee;
    box-shadow: 2px 2px 4px #eee;
}

table.docutils td, table.docutils th {
    border: 1px solid #888;
    padding: 0.25em 0.7em;
}

table.field-list, table.footnote {
    border: none;
    -moz-box-shadow: none;
    -webkit-box-shadow: none;
    box-shadow: none;
}

table.footnote {
    margin: 15px 0;
    width: 100%;
    border: 1px solid #eee;
    background: #fdfdfd;
    font-size: 0.9em;
}

table.footnote + table.footnote {
    margin-top: -15px;
    border-top: none;
}

table.field-list th {
    padding: 0 0.8em 0 0;
}

table.field-list td {
    padding: 0;
}

table.footnote td.label {
    width: 0px;
    padding: 0.3em 0 0.3em 0.5em;
}

table.footnote td {
    padding: 0.3em 0.5em;
}

dl {
    margin: 0;
    padding: 0;
}

dl dd {
    margin-left: 30px;
}

blockquote {
    margin: 0 0 0 30px;
    padding: 0;
}

ul, ol {
    margin: 10px 0 10px 30px;
    padding: 0;
}

pre {
    background: #eee;
    padding: 7px 30px;
    margin: 15px -30px;
    line-height: 1.3em;
}

dl pre, blockquote pre, li pre {
    margin-left: -60px;
    padding-left: 60px;
}

dl dl pre {
    margin-left: -90px;
    padding-left: 90px;
}

tt {
    background-color: #ecf0f3;
    color: #222;
    /* padding: 1px 2px; */
}

tt.xref, a tt {
    background-color: #FBFBFB;
    border-bottom: 1px solid white;
}

a.reference {
    text-decoration: none;
    border-bottom: 1px dotted #004B6B;
}

a.reference:hover {
    border-bottom: 1px solid #6D4100;
}

a.footnote-reference {
    text-decoration: none;
    font-size: 0.7em;
    vertical-align: top;
    border-bottom: 1px dotted #004B6B;
}

a.footnote-reference:hover {
    border-bottom: 1px solid #6D4100;
}

a:hover tt {
    background: #EEE;
}


@media screen and (max-width: 600px) {

    div.sphinxsidebar {
    	display: none;
    }

    div.document {
       width: 100%;

    }

    div.documentwrapper {
    	margin-left: 0;
    	margin-top: 0;
    	margin-right: 0;
    	margin-bottom: 0;
    }

    div.bodywrapper {
    	margin-top: 0;
    	margin-right: 0;
    	margin-bottom: 0;
    	margin-left: 0;
    }

    ul {
    	margin-left: 0;
    }

    .document {
    	width: auto;
    }

    .footer {
    	width: auto;
    }

    .bodywrapper {
    	margin: 0;
    }

    .footer {
    	width: auto;
    }

    .github {
        display: none;
    }

}

/* misc. */

.revsys-inline {
    display: none!important;
}


================================================
FILE: docs/_themes/ms/static/small_flask.css
================================================
/*
 * small_flask.css_t
 * ~~~~~~~~~~~~~~~~~
 *
 * :copyright: Copyright 2010 by Armin Ronacher.
 * :license: Flask Design License, see LICENSE for details.
 */

body {
  margin: 0;
  padding: 20px 30px;
}

div.documentwrapper {
  float: none;
  background: white;
}

div.sphinxsidebar {
  display: block;
  float: none;
  width: 102.5%;
  margin: 50px -30px -20px -30px;
  padding: 10px 20px;
  background: #333;
  color: white;
}

div.sphinxsidebar h3,
div.sphinxsidebar h4,
div.sphinxsidebar p,
div.sphinxsidebar h3 a {
  color: white;
}

div.sphinxsidebar a {
  color: #aaa;
}

div.sphinxsidebar p.logo {
  display: none;
}

div.document {
  width: 100%;
  margin: 0;
}

div.related {
  display: block;
  margin: 0;
  padding: 10px 0 20px 0;
}

div.related ul,
div.related ul li {
  margin: 0;
  padding: 0;
}

div.footer {
  display: none;
}

div.bodywrapper {
  margin: 0;
}

div.body {
  min-height: 0;
  padding: 0;
}

.rtd_doc_footer {
  display: none;
}

.document {
  width: auto;
}

.footer {
  width: auto;
}

.footer {
  width: auto;
}

.github {
  display: none;
}


================================================
FILE: docs/_themes/ms/theme.conf
================================================
[theme]
inherit = basic
stylesheet = flasky.css
pygments_style = flask_theme_support.FlaskyStyle

[options]
touch_icon =


================================================
FILE: docs/api_reference.rst
================================================
.. _api:

API Reference
=============

.. _timeseries:

TimeSeries
----------

In traces, a TimeSeries is similar to a dictionary that contains
measurements of something at different times. One difference is that
you can ask for the value at any time -- it doesn't need to be at a
measurement time. Let's say you're measuring the contents of a grocery
cart by the number of minutes within a shopping trip.

.. code:: python

    >>> cart = traces.TimeSeries()
    >>> cart[1.2] = {'broccoli'}
    >>> cart[1.7] = {'broccoli', 'apple'}
    >>> cart[2.2] = {'apple'}
    >>> cart[3.5] = {'apple', 'beets'}

If you want to know what's in the cart at 2 minutes, you can simply
get the value using :code:`cart[2]` and you'll see :code:`{'broccoli',
'apple'}`. By default, if you ask for a time before the first
measurement, you'll get `None`.

.. code:: python

    >>> cart = traces.TimeSeries()
    >>> cart[-1]
    None

If, however, you set the default when creating the TimeSeries, you'll
get that instead:

.. code:: python

    >>> cart = traces.TimeSeries(default=set())
    >>> cart[-1]
    set([])

In this case, it might also make sense to add the t=0 point as a
measurement with :code:`cart[0] = set()`.

Visualizing Time Series
++++++++++++++++++++++

The TimeSeries class provides a :code:`plot()` method for easy visualization of your data:

.. code:: python

    >>> ts = traces.TimeSeries()
    >>> ts[0] = 0
    >>> ts[1] = 2
    >>> ts[3] = 1
    >>> ts[5] = 0
    >>>
    >>> # Create a basic plot with default settings
    >>> fig, ax = ts.plot()

You can customize the plot appearance with various parameters:

.. code:: python

    >>> # Create a plot with linear interpolation and custom styling
    >>> fig, ax = ts.plot(
    ...     interpolate="linear",  # Use linear interpolation between points
    ...     figure_width=10,       # Set figure width in inches
    ...     linewidth=2,           # Set line thickness
    ...     marker="s",            # Use square markers
    ...     markersize=5,          # Set marker size
    ...     color="#FF5733"        # Use custom color
    ... )

The plot method returns matplotlib objects that you can further customize or save to a file:

.. code:: python

    >>> # Add title and labels
    >>> ax.set_title("My Time Series Data")
    >>> ax.set_xlabel("Time")
    >>> ax.set_ylabel("Value")
    >>>
    >>> # Save the plot to a file
    >>> fig.savefig("my_timeseries.png")

.. autoclass:: traces.TimeSeries
    :members:

.. _histogram:

Histogram
---------

.. autoclass:: traces.Histogram
    :members:

.. _eventseries:

EventSeries
-----------

An EventSeries represents a sequence of events that occur at specific times.
Unlike TimeSeries which tracks measurements (values) over time, EventSeries
only tracks when events occur, without associated values.

.. code:: python

    >>> # Track website login events
    >>> logins = traces.EventSeries([
    ...     "2023-05-01 08:15",
    ...     "2023-05-01 09:30",
    ...     "2023-05-01 10:45",
    ...     "2023-05-01 12:00"
    ... ])

EventSeries is useful for analyzing:

* Event frequencies and patterns
* Time intervals between events
* Event counts within specific time ranges
* Active cases over time (like support tickets, hospital stays)

.. code:: python

    >>> # Count events in a time range
    >>> logins.events_between("2023-05-01 08:00", "2023-05-01 10:00")
    2

    >>> # Get cumulative count of events over time
    >>> cumulative = logins.cumulative_sum()
    >>> cumulative["2023-05-01 11:00"]
    3

.. autoclass:: traces.EventSeries
    :members:


================================================
FILE: docs/conf.py
================================================
#
# traces documentation build configuration file, created by
# sphinx-quickstart
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

# If extensions (or modules to document with autodoc) are in another
# directory, add these directories to sys.path here. If the directory
# is relative to the documentation root, use os.path.abspath to make
# it absolute, like shown here.
import datetime
import os
import sys

sys.path.insert(0, os.path.abspath(".."))
sys.path.append(os.path.abspath("_themes"))
from recommonmark.parser import CommonMarkParser  # noqa: E402

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    "sphinx.ext.autodoc",
    "sphinx.ext.mathjax",
    "sphinx.ext.viewcode",
    "sphinx.ext.napoleon",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# The suffix(es) of source filenames.  You can specify multiple suffix
# as a list of string:
source_parsers = {
    ".md": CommonMarkParser,
}
source_suffix = [".rst", ".md"]

# The master toctree document.
master_doc = "index"

# General information about the project.
project = "traces"
copyright = f"2016-{datetime.date.today().year}, Mike Stringer"  # noqa: A001
author = "Mike Stringer"

# The version info for the project you're documenting, acts as
# replacement for |version| and |release|, also used in various other
# places throughout the built documents. The short X.Y version:
version = "0.7.0"
# The full version, including alpha/beta/rc tags:
release = "0.7.0"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = "en"

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = "ms"

# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = ["_themes"]

# The name of an image file (relative to this directory) to use as a favicon of
# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = "_static/img/favicon.ico"

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
html_sidebars = {
    "**": ["side-primary.html"],
}

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
html_show_copyright = True

# Output file base name for HTML help builder.
htmlhelp_basename = "tracesdoc"

latex_elements = {}

# Grouping the document tree into LaTeX files. List of tuples (source
# start file, target name, title, author, documentclass [howto,
# manual, or own class]).
latex_documents = [
    (
        master_doc,
        "traces.tex",
        "traces Documentation",
        "Mike Stringer",
        "manual",
    ),
]

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, "traces", "traces Documentation", [author], 1)]

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (
        master_doc,
        "traces",
        "traces Documentation",
        author,
        "traces",
        "One line description of project.",
        "Miscellaneous",
    ),
]


================================================
FILE: docs/examples.rst
================================================
.. _examples:

Examples
========

.. include:: goals.rst

This section has a few examples of how to do these things.

Read and manipulate
-------------------

Say we have a directory with a bunch of CSV files with information
about light bulbs in a home. Each CSV file has the wattage used by the
bulb as a function of time. Some of the light bulbs only send a signal
when the state changes, but some send a signal every minute. We can
read them with this code.

.. literalinclude:: ../examples/helloworld.py
   :lines: 10-35

The call to :code:`ts.compact()` will remove any redundant
measurements. Depending on how often your data changes compared to how
often it is sampled, this can reduce the size of the data
dramatically.

Basic analysis
--------------

Now, let's say we want to do some basic exploratory analysis of how
much power is used in the whole home. We'll first take all of the
individual traces and merge them into a single TimeSeries where the
values is the total wattage.

.. literalinclude:: ../examples/helloworld.py
   :lines: 37

The merged time series has times that are the union of all times in
the individual series. Since each time series is the wattage of the
lightbulb, the values after the sum are the total wattage used over
time. Here's how to check the mean power consumption in January.

.. literalinclude:: ../examples/helloworld.py
   :lines: 41-45

Let's say we want to break this down to see how the distribution of
power consumption varies by time of day.

.. literalinclude:: ../examples/helloworld.py
   :lines: 49-50

Visualizing Time Series
----------------------

You can easily visualize time series data using the built-in `plot()` method:

.. code-block:: python

   # Create a plot of the total power usage
   fig, ax = merged.plot(
       interpolate="previous",  # Use previous-value interpolation (default)
       figure_width=12,         # Width of the figure in inches
       linewidth=1.5,           # Line thickness
       marker="o",              # Circular markers
       markersize=3,            # Size of markers
       color="#007ACC"          # Blue color for the line
   )

   # Customize the plot
   ax.set_title("Total Home Power Usage")
   ax.set_xlabel("Time")
   ax.set_ylabel("Power (watts)")

   # Save or display the plot
   fig.savefig("power_usage.png")  # Save to file
   # plt.show()  # Or display it interactively

Or day of week.

.. literalinclude:: ../examples/helloworld.py
   :lines: 52-53

Finally, we just want to look at the distribution of power consumption
during business hours on each day in January.

.. literalinclude:: ../examples/helloworld.py
   :lines: 57-61

In practice, you'd probably be plotting these distribution and time
series using your tool of choice.

Transform to evenly-spaced
--------------------------

Now, let's say we want to do some forecasting of the power consumption
of this home. There is probably some seasonality that need to be
accounted for, among other things, and we know that `statsmodels
<http://statsmodels.sourceforge.net/>`_ and `pandas
<http://pandas.pydata.org/>`_ are tools with some batteries included
for that type of thing. Let's convert to a `pandas Series
<http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html>`_.

.. literalinclude:: ../examples/helloworld.py
   :lines: 68

That will convert to a regularly-spaced time series using a moving
average to avoid `aliasing <https://en.wikipedia.org/wiki/Aliasing>`_
(more info `here <http://scicomp.stackexchange.com/a/615>`_). At this
point, a good next step is the `excellent tutorial by Tom Augspurger
<http://tomaugspurger.github.io/modern-7-timeseries.html>`_, starting
with the *Modeling Time Series* section.


================================================
FILE: docs/goals.rst
================================================
Traces aims to make it simple to write *readable code* to:

- **Wrangle**. Read, write, and manipulate unevenly-spaced time series data
- **Explore**. Perform basic analyses of unevenly-spaced time series
  data without making an awkward / lossy transformation to
  evenly-spaced representations
- **Convert**. Gracefully transform unevenly-spaced times series data to
  evenly-spaced representations


================================================
FILE: docs/index.rst
================================================
.. traces documentation master file, created by
   sphinx-quickstart on Tue Sep 20 09:46:11 2016.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

traces
======

A Python library for unevenly-spaced time series analysis.

Why?
----

Taking measurements at irregular intervals is common, but most tools
are primarily designed for evenly-spaced measurements. Also, in the
real world, time series have missing observations or you may have
multiple series with different frequencies: it's can be useful to
model these as unevenly-spaced.

.. include:: goals.rst

Traces was designed by the team at `Datascope
<https://en.wikipedia.org/wiki/Datascope_Analytics>`__ based on several practical
applications in different domains, because it turns out :doc:`unevenly-spaced data is actually pretty great, particularly for sensor data analysis <unevenly-spaced>`.

Installation
------------

To install traces, run this command in your terminal:

.. code:: bash

    $ pip install traces

Quickstart: using traces
------------------------

To see a basic use of traces, let's look at these data from a light
switch, also known as *Big Data from the Internet of Things*.

.. figure:: _static/img/trace.svg
   :alt: light switch trace

The main object in traces is a :ref:`TimeSeries <timeseries>`, which
you create just like a dictionary, adding the five measurements at
6:00am, 7:45:56am, etc.

.. code:: python

    >>> time_series = traces.TimeSeries()
    >>> time_series[datetime(2042, 2, 1,  6,  0,  0)] = 0 #  6:00:00am
    >>> time_series[datetime(2042, 2, 1,  7, 45, 56)] = 1 #  7:45:56am
    >>> time_series[datetime(2042, 2, 1,  8, 51, 42)] = 0 #  8:51:42am
    >>> time_series[datetime(2042, 2, 1, 12,  3, 56)] = 1 # 12:03:56am
    >>> time_series[datetime(2042, 2, 1, 12,  7, 13)] = 0 # 12:07:13am

What if you want to know if the light was on at 11am? Unlike a
python dictionary, you can look up the value at any time even if it's
not one of the measurement times.

.. code:: python

    >>> time_series[datetime(2042, 2, 1, 11,  0, 0)] # 11:00am
    0

The ``distribution`` function gives you the fraction of time that the
``TimeSeries`` is in each state.

.. code:: python

    >>> time_series.distribution(
    >>>   start=datetime(2042, 2, 1,  6,  0,  0), # 6:00am
    >>>   end=datetime(2042, 2, 1,  13,  0,  0)   # 1:00pm
    >>> )
    Histogram({0: 0.8355952380952381, 1: 0.16440476190476191})

The light was on about 16% of the time between 6am and 1pm.

Adding more data...
+++++++++++++++++++

Now let's get a little more complicated and look at the sensor
readings from forty lights in a building.

.. figure:: _static/img/traces.svg
   :alt: many light switch trace

How many lights are on throughout the day? The merge function takes
the forty individual ``TimeSeries`` and efficiently merges them into
one ``TimeSeries`` where the each value is a list of all lights.

.. code:: python

    >>> trace_list = [... list of forty traces.TimeSeries ...]
    >>> count = traces.TimeSeries.merge(trace_list, operation=sum)

We also applied a ``sum`` operation to the list of states to get the
``TimeSeries`` of the number of lights that are on.

.. figure:: _static/img/count.svg
   :alt: many light switch count

How many lights are typically on during business hours, from 8am to
6pm?

.. code:: python

    >>> histogram = count.distribution(
    >>>   start=datetime(2042, 2, 1,  8,  0,  0),   # 8:00am
    >>>   end=datetime(2042, 2, 1,  12 + 6,  0,  0) # 6:00pm
    >>> )
    >>> histogram.median()
    17

The ``distribution`` function returns a :ref:`Histogram <histogram>`
that can be used to get summary metrics such as the mean or quantiles.

Tracking discrete events
+++++++++++++++++++++++

The traces library also provides an :ref:`EventSeries <eventseries>` class
for tracking discrete events that occur at specific times, like system
logins, errors, or customer interactions.

.. code:: python

    >>> logins = traces.EventSeries([
    ...     datetime(2042, 2, 1, 8, 15, 0),
    ...     datetime(2042, 2, 1, 9, 30, 0),
    ...     datetime(2042, 2, 1, 10, 45, 0),
    ... ])
    >>> logins.events_between(
    ...     datetime(2042, 2, 1, 8, 0, 0),
    ...     datetime(2042, 2, 1, 10, 0, 0)
    ... )
    2

EventSeries is especially useful for analyzing event frequencies, inter-event times,
and tracking active cases over time.

It's flexible
+++++++++++++

The measurements points (keys) in a ``TimeSeries`` can be in any units as
long as they can be ordered. The values can be anything.

For example, you can use a ``TimeSeries`` to keep track the contents
of a grocery basket by the number of minutes within a shopping trip.

.. code:: python

    >>> time_series = traces.TimeSeries()
    >>> time_series[1.2] = {'broccoli'}
    >>> time_series[1.7] = {'broccoli', 'apple'}
    >>> time_series[2.2] = {'apple'}          # puts broccoli back
    >>> time_series[3.5] = {'apple', 'beets'} # mmm, beets

To learn more, check the :ref:`examples <examples>` and the detailed
:ref:`reference <api>`.

More info
---------

.. toctree::
   :maxdepth: 2

   examples
   api_reference
   sorted_dict
   merge_strategies

Contributing
-------------

Contributions are welcome and greatly appreciated! Please visit `the
repository
<https://github.com/datascopeanalytics/traces/blob/master/CONTRIBUTING.md>`_
for more info.


================================================
FILE: docs/merge_strategies.rst
================================================
.. _merge_strategies:

Merge implementation strategies
===============================

Merging multiple TimeSeries is one of the most important operations in
traces. Given K TimeSeries with N total measurement points across all
of them, the merge produces a single TimeSeries where each value is a
list of all the input values at that time (or a function of all the
values if `operation` is given).

As a concrete example, consider two TimeSeries tracking whether a light
is on (1) or off (0):

.. code-block:: python

    >>> a = TimeSeries(default=0)
    >>> a[1] = 1
    >>> a[3] = 0

    >>> b = TimeSeries(default=0)
    >>> b[2] = 1
    >>> b[4] = 0

Without an operation, merge produces a TimeSeries where each value is
a list of the states of all inputs at that time:

.. code-block:: python

    >>> merged = TimeSeries.merge([a, b])
    >>> for t, v in merged:
    ...     print(t, v)
    1 [1, 0]
    2 [1, 1]
    3 [0, 1]
    4 [0, 0]

With ``operation=sum``, the list is reduced to a single value — here,
the count of lights that are on:

.. code-block:: python

    >>> count = TimeSeries.merge([a, b], operation=sum)
    >>> for t, v in count:
    ...     print(t, v)
    1 1
    2 2
    3 1
    4 0

The core challenge is iterating through all transitions in time order
while tracking the current state of each input series. There are
several ways to do this, each with different performance
characteristics. This page describes three approaches and their
tradeoffs.

This is useful context for reimplementing merge in another language —
the right choice depends on the expected workload.

The three approaches
--------------------

1. Naive (collect-keys)
~~~~~~~~~~~~~~~~~~~~~~~

The simplest approach: collect all unique measurement times across all
K series, then at each time, query every series for its value.

.. code-block:: python

    def naive_iter_merge(timeseries_list):
        # Collect all unique measurement times
        all_times = set()
        for ts in timeseries_list:
            for t, _v in ts:
                all_times.add(t)

        # At each time, query every series
        for t in sorted(all_times):
            yield t, [ts[t] for ts in timeseries_list]

**How it works:** Build a set of all times (O(N)), sort them (O(N log N)),
then for each of the T unique times, look up the value in each of the K
series via binary search (O(log N) per lookup).

**Complexity:** O(N log N + T × K × log N) time, O(T × K) memory for the
output state lists.

**Pros:**

- Dead simple to implement and understand.
- No auxiliary data structures beyond a set and a sorted list.
- Easy to port to any language — uses only sets, sorted arrays, and
  binary search.

**Cons:**

- Performs K binary searches at every unique time, even when only one
  series changed. This is the dominant cost: for K=1000 with 2
  transitions each, there are ~2000 unique times and each requires
  1000 lookups — 2 million binary searches total.
- Scales poorly with K. At K=1000, this approach is **40× slower**
  than the alternatives (see benchmarks below).

**When to use it:** For small K (under ~20 series) where simplicity
matters more than performance, or as a reference implementation for
testing.

This was the first approach used by the `traces JavaScript implementation
<https://github.com/stringertheory/traces-js>`_:

.. code-block:: javascript

    function merge(traceList, operation = (d) => d) {
      let keys = new Set(traceList.map((d) => d.list).flat());
      let result = new Trace([], operation(traceList.map((d) => d.defaultValue)));
      for (let k of keys) {
        result.set(k, operation(traceList.map((d) => d.get(k))));
      }
      return result;
    }

2. Priority queue (heap merge)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Use a min-heap to perform a K-way merge of the pre-sorted input series.
Each series contributes an iterator; the heap always contains the next
upcoming transition from each active series.

.. code-block:: python

    import heapq

    def heapq_iter_merge_transitions(timeseries_list):
        heap = []
        for index, ts in enumerate(timeseries_list):
            iterator = iter(ts)
            try:
                t, value = next(iterator)
            except StopIteration:
                pass
            else:
                heapq.heappush(heap, (t, index, value, iterator))

        state = [ts.default for ts in timeseries_list]
        while heap:
            t, index, next_value, iterator = heapq.heappop(heap)
            previous_value = state[index]
            state[index] = next_value
            yield t, index, previous_value, next_value

            try:
                t, value = next(iterator)
            except StopIteration:
                pass
            else:
                heapq.heappush(heap, (t, index, value, iterator))

**How it works:** The heap holds at most K entries (one per series).
Each ``heappop`` yields the next transition in time order. After
processing a transition, the next value from that series is pushed
back onto the heap.

**Complexity:** O(N log K) time (each of N transitions requires one
heap push and one heap pop, each O(log K)). O(K) memory for the heap
plus K iterator objects.

**Pros:**

- Only processes actual transitions, never queries a series that
  didn't change.
- Streaming: produces transitions lazily without materializing all
  data up front.

**Cons:**

- Each heap operation has Python function call overhead (``heapq.heappush``
  and ``heapq.heappop`` are C functions, but each call crosses the
  Python/C boundary).
- Maintains K live iterator objects in memory for the duration of the merge.
- For small K, the log K advantage over flat sort's log N is negligible,
  and the per-element overhead is higher.

**When to use it:** When N per series is very large (tens of thousands
or more) and K is small — the heap avoids materializing all N triples
and uses significantly less memory (see benchmarks). Also the right
choice when the input series are streams (e.g. reading from files or
network sources) rather than in-memory data, since it produces
transitions lazily without buffering.

**Note on thread-safe wrappers:** Python's ``queue.PriorityQueue`` wraps
``heapq`` with a threading lock, adding acquire/release overhead on every
push and pop. For single-threaded merge, use ``heapq`` directly.

3. Flat sort (extract and sort)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Extract all (time, index, value) triples from every series into a single
list, sort it once, then iterate linearly.

.. code-block:: python

    def flat_sort_iter_merge_transitions(timeseries_list):
        triples = []
        for index, ts in enumerate(timeseries_list):
            for t, v in ts:
                triples.append((t, index, v))
        triples.sort()

        state = [ts.default for ts in timeseries_list]
        for t, index, next_value in triples:
            previous_value = state[index]
            state[index] = next_value
            yield t, index, previous_value, next_value

**How it works:** Flattening all transitions into a single list and sorting
turns the K-way merge into a standard sort problem. The subsequent
iteration is a simple linear scan with no function call overhead per
element (no ``heappush``/``heappop``).

**Complexity:** O(N log N) time for the sort, O(N) memory for the
triples list. The log N factor is theoretically worse than the priority
queue's log K, but in practice timsort's lower constant factor wins for
most workloads.

**Pros:**

- Fastest in practice for in-memory data (see benchmarks).
- No iterator objects or heap — just a flat list of tuples.
- Python's timsort exploits existing order within each series'
  contribution, performing well on the partially-sorted input.

**Cons:**

- Materializes all transitions at once. Not suitable for streaming
  inputs that don't fit in memory.
- O(N) memory for the triples list (though this is typically small
  compared to the TimeSeries objects themselves).

**When to use it:** For in-memory data, which is the common case.
This is the current default in traces.

This is what traces uses as of version 0.7.
Performance characteristics are discussed below and benchmarks can be
reproduced via ``python experiments/bench_merge_strategies.py``.

Benchmarks
----------

All benchmarks on a 2021 Apple M1 MacBook Pro, Python 3.12, minimum of
3 runs. Series values are integers; operation is ``sum``.

Many series, few transitions per series
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is the "light switch" or "ticket open/close" pattern: many boolean
or categorical series with only a few state changes each. Each series
has 2 transitions, so N (total transitions) = K × 2.

These benchmarks call ``merge(operation=sum)``, which goes through
``iter_merge`` and copies the full K-element state list at each yield.

.. list-table::
   :header-rows: 1
   :widths: 10 10 20 20 20

   * - K
     - N total
     - Naive
     - Priority queue
     - Flat sort
   * - 10
     - 20
     - 0.1 ms / 4 KB
     - 0.1 ms / 5 KB
     - 0.1 ms / 4 KB
   * - 50
     - 100
     - 1.8 ms / 14 KB
     - 0.3 ms / 18 KB
     - 0.3 ms / 13 KB
   * - 100
     - 200
     - 6.6 ms / 19 KB
     - 0.7 ms / 29 KB
     - 0.6 ms / 20 KB
   * - 500
     - 1,000
     - 150 ms / 81 KB
     - 6.0 ms / 172 KB
     - 5.1 ms / 119 KB
   * - 1,000
     - 2,000
     - 588 ms / 234 KB
     - 17.7 ms / 300 KB
     - 15.3 ms / 213 KB

At K=1000, the naive approach is **38× slower** than flat sort. The
naive approach's cost is dominated by performing K binary searches at
each of the ~2000 unique times (2 million lookups). The priority queue
and flat sort appear close here, with flat sort ~15% faster — but this
understates the difference (see "Consuming transitions directly" below
for why).

Few series, many transitions per series
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

These benchmarks also call ``merge(operation=sum)``. N/series is
the number of transitions per series; N total = K × N/series.

.. list-table::
   :header-rows: 1
   :widths: 8 10 10 20 20 20

   * - K
     - N/series
     - N total
     - Naive
     - Priority queue
     - Flat sort
   * - 2
     - 100
     - 200
     - 0.5 ms / 25 KB
     - 0.4 ms / 18 KB
     - 0.4 ms / 18 KB
   * - 2
     - 1,000
     - 2,000
     - 8.6 ms / 263 KB
     - 6.2 ms / 138 KB
     - 5.9 ms / 136 KB
   * - 5
     - 100
     - 500
     - 2.2 ms / 67 KB
     - 1.3 ms / 36 KB
     - 1.3 ms / 35 KB
   * - 5
     - 1,000
     - 5,000
     - 35 ms / 790 KB
     - 16.9 ms / 448 KB
     - 16.4 ms / 468 KB

With small K, all three approaches are closer in speed. The naive
approach is still 1.5–2× slower due to the redundant binary searches.
The priority queue and flat sort are nearly identical here — with K=5,
the heap holds only 5 entries and log K is tiny.

iter_merge memory (full state lists)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``iter_merge`` yields ``(time, list_of_all_values)`` at each unique time.
Regardless of strategy, this requires copying a K-element list at each
yield. For large K, this copy dominates memory. Each series has 2
transitions (N total = K × 2).

.. list-table::
   :header-rows: 1
   :widths: 10 10 20 20 20

   * - K
     - N total
     - Naive
     - Priority queue
     - Flat sort
   * - 100
     - 200
     - 6.4 ms / 192 KB
     - 0.5 ms / 174 KB
     - 0.3 ms / 174 KB
   * - 500
     - 1,000
     - 150 ms / 4.1 MB
     - 3.2 ms / 3.9 MB
     - 3.1 ms / 4.0 MB
   * - 1,000
     - 2,000
     - 588 ms / 17.0 MB
     - 9.2 ms / 15.4 MB
     - 10.9 ms / 15.4 MB

The priority queue and flat sort look nearly identical here. This is
because the K-element list copies at each yield dominate both time and
memory, swamping the sort-vs-heap difference.

Consuming transitions directly (many series)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The flat sort advantage becomes clear when transitions are consumed
directly — without the O(K) list copy overhead. This is the pattern
used by ``count_by_value`` and any consumer that maintains its own
incremental state. Each series has 2 transitions (N total = K × 2).

.. list-table::
   :header-rows: 1
   :widths: 10 10 25 25

   * - K
     - N total
     - Priority queue
     - Flat sort
   * - 100
     - 200
     - 0.3 ms / 12 KB
     - 0.1 ms / 4 KB
   * - 500
     - 1,000
     - 1.7 ms / 82 KB
     - 0.8 ms / 24 KB
   * - 1,000
     - 2,000
     - 3.5 ms / 175 KB
     - 1.7 ms / 53 KB
   * - 5,000
     - 10,000
     - 25 ms / 1.8 MB
     - 13 ms / 0.9 MB

Flat sort is **2× faster** and uses **3× less memory** than the
priority queue when consuming transitions directly with many series.
The speed difference comes from timsort's cache-friendliness and lower
per-element overhead (no ``heappush``/``heappop`` calls per transition).
The memory difference comes from eliminating K iterator objects and
the 4-tuple heap entries (which include iterator references) in favor
of a flat list of 3-tuples.

This matters for ``count_by_value``: at K=10,000 with 2 transitions per
series, ``count_by_value`` runs in 0.16s with flat sort vs 0.22s with
a priority queue — a 27% improvement that comes entirely from the
underlying sort strategy.

Consuming transitions directly (few series, very many transitions)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

With few series and very many transitions per series (small K, large N),
the priority queue's O(N log K) advantage over flat sort's O(N log N)
should theoretically win. Does it?

.. list-table::
   :header-rows: 1
   :widths: 8 10 10 25 25

   * - K
     - N/series
     - N total
     - Priority queue
     - Flat sort
   * - 2
     - 10,000
     - 20,000
     - 14 ms / 1.3 MB
     - 14 ms / 1.9 MB
   * - 2
     - 50,000
     - 100,000
     - 73 ms / 6.1 MB
     - 81 ms / 9.8 MB
   * - 2
     - 100,000
     - 200,000
     - 149 ms / 12.1 MB
     - 161 ms / 19.7 MB
   * - 2
     - 500,000
     - 1,000,000
     - 765 ms / 61.2 MB
     - 833 ms / 99.6 MB
   * - 3
     - 50,000
     - 150,000
     - 86 ms / 9.2 MB
     - 121 ms / 13.3 MB

At K=2 with 1M total transitions, the priority queue is **~10% faster**
in time. But the real win is **memory**: the heap uses 61 MB vs flat
sort's 100 MB. This is because flat sort materializes all N triples
at once, while the heap only holds K=2 entries at any time. The
memory ratio approaches N/K as N grows.

At K=3 with 150k transitions, the heap is ~30% faster — the log K = 1.6
vs log N = 17.2 ratio starts to matter when N is large enough.

**The takeaway:** the priority queue wins on memory when N is large
relative to K, because it doesn't materialize the full triples list.
The speed advantage is modest (10–30%) and only appears at very high
N. For the common traces use case — many entities with few state
changes each (large K, small N per series) — flat sort is faster and
uses less memory.

**The lesson:** the choice between priority queue and flat sort matters
most when the consumer processes transitions directly. When the
consumer goes through ``iter_merge`` (which copies K-element lists),
the copy overhead dominates and the sort strategy barely matters.

Choosing an approach
--------------------

**Use flat sort** (the traces default) when the data is in memory.
It's the fastest approach for the common case and has no complex data
structures to implement — just a list, a sort, and a linear scan.

**Use a priority queue** when N per series is very large (tens of
thousands+) and K is small — the heap avoids materializing all N
triples in memory (61 MB vs 100 MB at K=2, N=1M). Also the right
choice when inputs are streams (data arriving over time, reading from
files) since it produces transitions lazily without buffering.

**Use the naive approach** for simplicity when K is small (under ~20)
and correctness matters more than performance. It's the easiest to
implement, test, and reason about. It's also a good reference
implementation for validating the other approaches.

Avoiding O(K) copies: transitions vs. full state
-------------------------------------------------

All three approaches above can yield either full state lists (what
``iter_merge`` does) or individual transitions (what
``iter_merge_transitions`` does). The choice affects downstream
consumers:

- **Full state lists** are convenient when the consumer needs the
  complete picture at each time (e.g., applying an arbitrary operation
  like ``sum`` over all K values). The cost is O(K) per yield for the
  list copy.

- **Transitions** yield O(1) per event and are better when the consumer
  can maintain its own state incrementally. ``count_by_value`` uses
  this: it keeps a ``{value: count}`` dict and adjusts two entries per
  transition (decrement the old value's count, increment the new
  value's count).

For K=1000 with 2 transitions each, ``iter_merge`` copies 2000 lists of
1000 elements (2M element copies, ~15 MB). ``iter_merge_transitions``
yields 2000 individual tuples (~0.2 MB for the triples list). The
algorithmic improvement is independent of which sort strategy is used.

Reproducing the benchmarks
--------------------------

You can reproduce these benchmarks by running::

    python experiments/bench_merge_strategies.py


================================================
FILE: docs/sorted_dict.rst
================================================
.. _sorted_dict:

Internal sorted dictionary
==========================

Traces uses an internal ``SortedDict`` class (in ``traces.sorted_dict``)
to store the time-value pairs in a ``TimeSeries``. This is a lightweight
implementation built on Python's ``dict`` and ``bisect`` module, with no
external dependencies.

Previously, traces used ``sortedcontainers.SortedDict`` for this
purpose. The `sortedcontainers <https://grantjenks.com/docs/sortedcontainers/>`_
library is an excellent, well-tested, pure-Python library for sorted
data structures.

Design
------

The built-in ``SortedDict`` maintains two data structures:

- A Python ``dict`` for O(1) key-value lookups
- A sorted ``list`` of keys for ordered iteration and binary search via
  the ``bisect`` module

This design has different performance characteristics than
``sortedcontainers.SortedDict``, which uses a B-tree-like structure
(a list of sublists) that provides more balanced performance across
operations.

Performance comparison
----------------------

Benchmarks were run using the full ``TimeSeries`` API (not just raw
data structure operations), with data sizes from N=100 to N=100,000.
The ratio column shows ``sortedcontainers`` time divided by built-in
time, so values greater than 1x indicate the built-in is faster.

**Where the built-in SortedDict is faster:**

- **Random lookups**: 1.6--3.3x faster across all sizes. The built-in
  uses O(1) dict lookup when the key exists and falls back to
  ``bisect`` otherwise. This advantage grows with N.
- **Iterating periods and computing distributions**: 1.4--3.7x faster
  across all sizes. These operations iterate over sorted keys and
  look up values, benefiting from the same dict + bisect combination.
- **Set interval**: 3.3--4.5x faster across all sizes. The built-in
  uses a single list-slice deletion to remove a range of keys,
  while the ``sortedcontainers`` path deletes keys individually.
- **Building incrementally at small N** (under ~1,000): 1.3--1.5x
  faster due to lower per-operation overhead.

**Where sortedcontainers.SortedDict is faster:**

- **Building incrementally at large N**: At N=10,000,
  ``sortedcontainers`` is 1.6x faster; at N=100,000 it is 10x
  faster. The built-in uses ``bisect.insort``, which has O(n) cost
  per insertion due to list element shifting. ``sortedcontainers``
  uses a B-tree-like structure with O(log n) amortized insertions.
  This only applies to individual insertions (``ts[time] = value``
  in a loop); using ``set_many()`` avoids this penalty entirely.

**Where they are comparable:**

- **Building from data** and **building with set_many**: Within a
  few percent of each other at all sizes. Both paths use bulk
  insertion (``dict.update`` + ``sorted``) rather than per-element
  insertion.

Bulk insertion with set_many
----------------------------

``TimeSeries.set_many(data)`` accepts an iterable of ``(time, value)``
pairs or a dictionary, and inserts all points in a single operation.
This avoids the per-element ``bisect.insort`` cost that makes
individual insertions slow at large N::

    # Instead of this:
    for time, value in data:
        ts[time] = value

    # Use this:
    ts.set_many(data)

``set_many`` accepts generators, so data does not need to be
materialized into a list first. ``from_csv`` and ``from_json`` use
``set_many`` internally.

Choosing an implementation
--------------------------

The built-in ``SortedDict`` is a good default for most use cases.
Typical time series workloads involve loading data in bulk (from files,
databases, or lists of measurements) and then performing read
operations like lookups, ``distribution()``, or ``iterperiods()``.
The built-in is faster for all of these read operations.

``sortedcontainers.SortedDict`` is a better choice if your workload
involves building very large time series incrementally through many
individual, random-order insertions (e.g., more than 10,000 points
added one at a time) and you cannot use ``set_many()`` to batch them.

Reproducing the benchmarks
--------------------------

You can reproduce these benchmarks by running::

    python experiments/bench_sorted_dict.py


================================================
FILE: docs/unevenly-spaced.rst
================================================
# Unevenly Spaced Data

September 26, 2016

As the Internet of Things (IoT) comes of age, we’re seeing more and more data from event-triggered sensors instead of sensors that record measurements at regular time intervals. These event-triggered sensors give rise to `unevenly-spaced time series <https://en.wikipedia.org/wiki/Unevenly_spaced_time_series>`__. Many analysts will immediately convert unevenly-spaced data to evenly-spaced time series to be compatible with existing sensor data analytics tools, but we have found that the conversion is usually unnecessary, and sometimes even causes problems.

## Unevenly-spaced data is actually pretty great

Imagine a wireless sensor that measures when a light is on.

The sensor has two options: it can send the signal only when the light is switched on or off, or it can send a signal to a base station to indicate whether the light is on every second.

The former, event-driven approach has several advantages: (FOOTNOTE: It also comes with a potential disadvantage that missed signals can cause larger errors. For example, if the wireless connection is unreliable and the last “switched turned off” signal is missed at the end of the day, you could inadvertently make the mistake that the light was on all night long. In this case it can often make sense to include an infrequent “heartbeat” signal, say every hour, that prevents very large measurement errors in the event of dropped signal: this still only requires about 1/60 of the energy-consuming wireless signals to be sent.)

Energy usage in sensor data collection. Sending energy-consuming wireless signals only when necessary will preserve battery as long as events occur less often than you’d be sending regular updates
Time resolution of sensor data processing. You know precisely when the state changed without needing to implement buffering logic on the sensor itself between regular signals.
Reduces redundancy in sensor data storage. No redundancy, without needing to implement compression logic on the base station.
These practical issues are especially important with increasingly more “things” that are wirelessly sending data. Let’s consider a quick calculation.

Suppose you record if a light bulb is on every second (maybe you’ve got a Hue or WeMo lightbulb). In a year, then, you’ll record about 86 thousand data points per day, or about 32 million data points in a year for just one light bulb. If you have 40 light bulbs in your home (the average number of lightbulbs in a U.S. home), that is more than 1.2 billion data points for your home in a year: BIG DATA ;)

Suppose you only turn on and off a light 10 times a day. If you collect your data in an event-driven manner, you will only have 20 data points per day, about 7 thousand data points per year, or about 290 thousand data points for your home. It’s more than a 4,000x reduction in the number of measurements to store!

## Don’t get rid of your unevenly-spaced data

When analysts are presented with unevenly-spaced sensor data, they usually convert the unevenly-spaced data to a evenly-spaced time series by regular sampling or linear interpolation. This conversion helps get the data into a format that are used by the most common tools for time series analysis. In addition to the constraints on data size, this method also presents other practical challenges:

It is easy to make mistakes. Since evenly-spaced time series are usually stored without timestamps (in an array, along with the start time and time interval), it’s easy to use the wrong time units — conversions are `notoriously error-prone <https://en.wikipedia.org/wiki/Mars_Climate_Orbiter>`__ — or mix up when the data was recorded.
It encourages bloat. If you have data from several sources with different time resolution, the usual approach is to sample at the smallest time resolution. You can end up with a time series that is sampled every second from a sensor that samples every hour.
Beyond the practical challenges, there are `technical reasons to be careful <http://www.eckner.com/papers/unevenly_spaced_time_series_analysis.pdf>`__ when converting unevenly-spaced data to regular time series including:

Data loss and dilution. You lose data that are closely spaced, and you add redundant data points when the data are too sparse.
Time information. The duration between each measurement can contain useful information about the data. For example, based on the frequency and duration of the light switching on or off, we can safely say that the second house is more likely to use an automated light switch than the first house.

## Traces deals gracefully with unevenly-spaced data

At Datascope, we’re increasingly finding ourselves helping clients with data from battery-powered sensors that are attached to “things”. In response, we built a lightweight Python package called traces to simplify the reading, writing, and analysis of unevenly-spaced data.

For example, if you want to know how many lightbulbs are turned on given the data from all light bulbs in your house, you can get this information using a very simple syntax.

We’ve found that handling unevenly-spaced data natively is not just useful for sensor data. For example, it’s great for handling time series with missing observations or aggregating multiple time series taken at differing regular intervals. We hope you find it useful, and if you’re interested, we welcome contributions to the code!

Contributors to this post
headshot of Yoke Peng Leong
headshot of Mike Stringer


================================================
FILE: docs-md/index.md
================================================
# boodle doodle


================================================
FILE: docs-md/modules.md
================================================
::: traces.timeseries

::: traces.timeseries.TimeSeries
:docstring:
:members:


================================================
FILE: docs-md/stylesheets/extra.css
================================================
:root > * {
  --md-mermaid-label-bg-color: rgba(255, 255, 255, 0.9);
}


================================================
FILE: examples/Plot.ipynb
================================================
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "%config InlineBackend.figure_format = 'retina'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import traces"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = traces.TimeSeries()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts[0] = 0\n",
    "ts[1] = 1\n",
    "ts[2] = 0\n",
    "ts[5] = 2\n",
    "ts[10] = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABU8AAADFCAYAAABkSAN6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO3de5Bc110n8K8iW1KkSGjFGDlYKyUSC1RMBAGHJEAqDgnaJRQGli2eYQlZvGdJeInHQiU8QsDFowCR3SxwooUQ4yVAFQEECYU34IgKjyJxyDqQsLAWq7EUS6uxIqSMrJFHmf2je4Qj91gt1DO3T8/nU6VqT/ftvr+r0de3+9fnnrNmYWEhAAAAAAB8vKd0XQAAAAAAwDjSPAUAAAAAGEDzFAAAAABgAM1TAAAAAIABNE8BAAAAAAbQPAUAAAAAGEDzFAAAAABgAM1TAAAAAIABNE8BAAAAAAbQPAUAAAAAGEDzFAAAAABgAM1TAAAAAIABNE8BAAAAAAbQPAUAAAAAGOCGUb1QKWVrkv1JvjLJM5NcTPK3Sd6c5JdqrZdGtS8AAAAAgOW2ZmFh4bpfpJTyKUnemWRX/66HkmxLsqn/8x8l+ZJa69x17wwAAAAAYAVc98jTUsraJL+dXuP0j5N8c631H0opa5J8UZJfTvKSJD+S5Puvd38DXH/3FwAAAACYdGuu+QnXO/K0lPLSJP8zyYeTfGqtdfaKx1+S3qjUf0yyrdb6seva4RNpngIAAAAAV3PNzdNRzHm6p3/71isbp333JZlN8glJtid5eAT7BACAJ3j00Udz77335qGHHsrOnTuzb9++bNiwoeuyAADGivdMwxtF8/RQkk9LcmCJxxeSLI42fWwE+1u1Tp06lSS56aabOq4EuBp5hTbI6mR54IEHcuedd2ZmZubyfVNTUzl48GD27t3bYWWMgrxCG2QVxp/3TNdmJAtGPZlSyvOT/HmSD9Van7UMu1g1l+0fOXIkSbJ79+6OKwGuRl6hDbI6OS5cuJAXvehFH/chYNHU1FQOHz5sNEXj5BXaIKsw3rxn6uay/SWVUp6S5Cf6P/74NTzv/mG3rbUm6f0P+vH/cz5x4kTOnz+f7du3Z9OmTUmSs2fPZmZmJps3b778Ldj8/Hymp6ezdu3a7Nq16/Lzjx07losXL+aWW27J+vXrkySnT5/OmTNnsnXr1mzbti1JMjc3l+PHj2fdunXZsWPH5ecfPXo0ly5dys6dO3PDDb2/5lOnTuXcuXOZmprKli1bkiSzs7M5efJkNm7cmJtvvvny8wedcG688cY89thjmZ2dnZhjmsTfk2NyTFu3bs3U1NTEHdMk/p4ck2OamprKzMzMqngfMenH9Ed/9EcDPwQkyczMTG699daBjwEA0DMzM5N77rkn3/AN3zCW7/eu5z3s9Xyh85R/9jOH85okL0ry+0nuWeZ9Tbwbb7yx6xKAIW3ZsuXyiQEYX3I6Oaanp7suAQCgeQ8/bKmiKy3bZfullC9P8rYkR5PcVmt9ZFl2tIou2wcAYLBDhw5l//79Sz5+4MCB3HHHHStYEQDA+PGe6dov21+W5mkp5bYkf5LkUpLPr7U+MPKd/JNV0zydnZ1NksvDlIHxJa/QBlmdHObvmnzyCm2QVRhv3jNde/N05Jftl1J2Jvm9JOuTfM0yN05XlZMnT+bkyZNdlwEMQV6hDbI6OTZs2JCDBw9ennN60eLKsRP+IWBVkFdog6zCePOe6dqNdMGoUsqW9OY3vTnJd9Za3z7K11/tNm7c2HUJwJDkFdogq5Nl7969OXz48OXFoQ4cOJB9+/b5EDAh5BXaIKsw/hbfM/3mb/5mPvzhD+dZz3qW90xPYmSX7ZdSbkhyKMkXJ/mFJK+uta7EJfWr5rJ9AACubs+ePUmSBx98sONKAAAYM91ctl9KWZPkDek1Tu9N8u0r1DgFAAAAAFgWo5rz9FX9Px9K8lW11vkRvS4AAAAAQCeu+7L9UsqmJDNJNvRvH1li04Ukb6q1HriuHQ5+3VXhyJEjSZLdu3d3XAlwNfIKbZDVyeSy/ckkr9AGWYV2rNK8XvNl+6NYMOqxJO9P8vwkU/0/S3nGCPYHAAAAALDsRrZgVIeaPwAAAEbHyFMAAJbQzYJRAAAAAACTRvMUAAAAAGAAzdOGnDhxIidOnOi6DGAI8gptkFVoh7xCG2QV2iGvwxnFglGskPPnz3ddAjAkeYU2yCq0Q16hDbIK7ZDX4WieNmT79u1dlwAMSV6hDbIK7ZBXaIOsQjvkdTiapw3ZtGlT1yUAQ5JXaIOsQjvkFdogq9AOeR2OOU8BAAAAAAbQPG3I2bNnc/bs2a7LAIYgr9AGWYV2yCu0QVahHfI6HJftN2RmZiZJsmXLlo4rAa5GXqENsgrtkFdog6xCO+R1OJqnDdm8eXPXJQBDkldog6xCO+QV2iCr0A55Hc6ahYWFrmu4Xs0fAAAAo7Nnz54kyYMPPthxJQAAjJk11/oEc54CAAAAAAygedqQ+fn5zM/Pd10GMAR5hTbIKrRDXqENsgrtkNfhaJ42ZHp6OtPT012XAQxBXqENsgrtkFdog6xCO+R1OBaMasjatWu7LgEYkrxCG2QV2iGv0AZZhXbI63AsGAUAwESxYBQAAEuwYBQAAAAAwChongIAAAAADKB52pBjx47l2LFjXZcBDEFeoQ2yCu2QV2iDrEI75HU4FoxqyMWLF7suARiSvEIbZBXaIa/QBlmFdsjrcCwY1ZC5ubkkyfr16zuuBLgaeYU2yOpksmDUZJJXaIOsQjtWaV6vecEoI08bssr+MUPT5BXaIKvQDnmFNsgqtENeh2POUwAAAACAATRPG3L69OmcPn266zKAIcgrtEFWoR3yCm2QVWiHvA5H87QhZ86cyZkzZ7ouAxiCvEIbZBXaIa/QBlmFdsjrcMx52pCtW7d2XQIwJHmFNsgqtENeoQ2yCu2Q1+GsWVhofrH65g8AAIDR2bNnT5LkwQcf7LgSAADGzJprfYLL9gEAAAAABtA8bcjc3Fzm5ua6LgMYgrxCG2QV2iGv0AZZhXbI63A0Txty/PjxHD9+vOsygCHIK7RBVqEd8gptkFVoh7wOx4JRDVm3bl3XJQBDkldog6xCO+QV2iCr0A55HY4FowAAmCgWjAIAYAkWjAIAAAAAGAXNUwAAAACAATRPG3L06NEcPXq06zKAIcgrtEFWoR3yCm2QVWiHvA7HglENuXTpUtclAEOSV2iDrEI75BXaIKvQDnkdzrIuGFVK+Ywkv5jk05O8rNb6l8uwm1WzYNT8/HyS5IYb9Lxh3MkrtEFWJ5MFoyaTvEIbZBXasUrzes0LRi3b304p5eVJ3pTkqf27viTJcjRPV41V9o8Zmiav0AZZhXbIK7RBVqEd8jqckf8tlVJuTPJzSV6VZD7JB5I8O8naUe8LAAAAAGC5LMeCUXel1zg9muSFSd62DPtYlU6dOpVTp051XQYwBHmFNsgqtENeoQ2yCu2Q1+EsR/P03Ul+Jslzaq1/sQyvv2qdO3cu586d67oMRujRRx/N7/7u7+aNb3xjDh06lAsXLnRdEiMir9AGWYV2yCu0QVahHfI6nJFftl9rPZTk0Khfl2RqaqrrEhihBx54IHfeeWdmZmYu3zc1NZWDBw9m7969HVbGKMgrtEFWoR3yCm2QVWiHvA7HzLAN2bJlS9clMCIXLlx4QuM0SWZmZnLnnXfm8OHD2bBhQ0fVMQryCm2QVWiHvEIbZBXaIa/DGcvmaSnl/mG3rbUmSY4cOZLdu3dfvv/EiRM5f/58tm/fnk2bNiVJzp49m5mZmWzevDk33XRTkmR+fj7T09NZu3Ztdu3adfn5x44dy8WLF3PLLbdk/fr1SZLTp0/nzJkz2bp1a7Zt25YkmZuby/Hjx7Nu3brs2LHj8vOPHj2aS5cuZefOnZdXLzt16lTOnTuXqampy/9AZ2dnc/LkyWzcuDE333zz5ecfOXIkSRzThB7Tvffe+4TG6aKZmZnceuutAx+jLbfffnt+/ud/fqz+7SWTlyfH5Jgck2O68piuNAnHNIm/J8fkmByTY3JMjskxOaaVOqbHv+a1Wo45T1km8/PzXZfAiExPT3ddAivgXe96V9clAFcxOzvbdQnAkB599FGZhQbMzs5mbm6u6zKAISwsLDi3DmHNwsLCsu6glPK6JD+c5K5a6w8swy6W9wDGyKAOPG06dOhQ9u/fv+TjBw4cyB133LGCFTFqe/bsSZI8+OCDHVcCPBnn1snk/8GTSV6hDbIK7VileV1zrU8Yy8v2GWzjxo1dl8CI7Nu3L1NTUwMv3Z+amsq+ffs6qApg9XFuhXbIK7RBVqEd8joczdOGPH4eCNq2YcOGHDx48AmLRk1NTeXgwYMWiwJYIc6t0A55hTbIKrRDXodjzlPoyN69e3P48OHLPx84cCCHDx/O3r17O6wKAAAAgEVGnkKHHj/C1BynAAAAAOPFyNOGHDly5PJkvgDA9XNuhXbIK7RBVqEd8joczVMAAAAAgAFctt+Q3bt3d10CAEwU51Zoh7xCG2QV2iGvw1mJkafvSTLbvwUAAAAAaMKyjzyttb49ydOWez8AAAAAAKNkztOGnDhxIidOnOi6DACYGM6t0A55hTbIKrRDXodjztOGnD9/vusSAGCiOLdCO+QV2iCr0A55HY7maUO2b9/edQkAMFGcW6Ed8gptkFVoh7wOR/O0IZs2beq6BACYKM6t0A55hTbIKrRDXodjzlMAAAAAgAE0Txty9uzZnD17tusyAGBiOLdCO+QV2iCr0A55HY7L9hsyMzOTJNmyZUvHlQDAZHBuhXbIK7RBVqEd8joczdOGbN68uesSAGCiOLdCO+QV2iCr0A55HY7maUNuuummrksAgIni3ArtkFdog6xCO+R1OOY8BQAAAAAYQPO0IfPz85mfn++6DACYGM6t0A55hTbIKrRDXoejedqQ6enpTE9Pd10GAEwM51Zoh7xCG2QV2iGvwzHnaUPWrl3bdQkAMFGcW6Ed8gptkFVoh7wOR/O0Ibt27eq6BACYKM6t0A55hTbIKrRDXofjsn0AAAAAgAE0TwEAAAAABtA8bcixY8dy7NixrssAgInh3ArtkFdog6xCO+R1OOY8bcjFixe7LgEAJopzK7RDXqENsgrtkNfhaJ425JZbbum6BACYKM6t0A55hTbIKrRDXoejedqQ9evXd10CAEwU51Zoh7xCG2QV2iGvwzHnKQAAAADAAJqnDTl9+nROnz7ddRkAMDGcW6Ed8gptkFVoh7wOR/O0IWfOnMmZM2e6LgMAJoZzK7RDXqENsgrtkNfhmPO0IVu3bu26BACYKM6t0A55hTbIKrRDXoejedqQbdu2dV0CAEwU51Zoh7xCG2QV2iGvw3HZPgAAAADAAJqnDZmbm8vc3FzXZQDAxHBuhXbIK7RBVqEd8joczdOGHD9+PMePH++6DACYGM6t0A55hTbIKrRDXodjztOGrFu3rusSAGCiOLdCO+QV2iCr0A55HY7maUN27NjRdQkAMFGcW6Ed8gptkFVoh7wOx2X7AAAAAAADaJ4CAAAAAAygedqQo0eP5ujRo12XAQATw7kV2iGv0AZZhXbI63DMedqQS5cudV0CAEwU51Zoh7xCG2QV2iGvw9E8bcjOnTu7LgEAJopzK7RDXqENsgrtkNfhaJ425IYb/LoAYJScW6Ed8gptkFVoh7wOZ6R/S6WUFyT5/iRfkGRLkoeS/E6Su2qtj4xyXwAAAAAAy2lkC0aVUr4uyZ8muSPJhiQPJ9mVZH+S+0spO0a1r9Xq1KlTOXXqVNdlAMDEcG6FdsgrtEFWoR3yOpyRNE9LKc9N8pYkC0m+O8m2WuvOJM9Icm96TdR3lFKMB74O586dy7lz57ouAwAmhnMrtENeoQ2yCu2Q1+GMqpl5V/+1Xldr/dnFO2utD5VSviLJ/UmeneRrk/zqiPa56kxNTXVdAgBMFOdWaIe8QhtkFdohr8O57pGnpZQ9Sb4oyUeS/PSVj9dazyd5ff/Hb7ne/a1Wjz76aO67777cfffdOXToUC5cuNB1ScASHn300cv/La8w3rZs2ZItW7Z0XQYwBHmFNsgqtENehzOKkae392/fUWudXWKbQ0nmkjy3lPK0WutHR7DfVeOBBx7InXfemZmZmcv3TU1N5eDBg9m7d2+HlQFXWszrov3798srAAAANGoUc57e1r9971Ib9JuqH0yvWat7cA0uXLjwhMZpkszMzOTOO+80og3GiLxCe2ZnZzM7u9R3v8A4kVdog6xCO+R1OKMYefqJ/duHrrLddJLnPG77JZVS7h9257XWJMmRI0eye/fuy/efOHEi58+fz/bt27Np06YkydmzZzMzM5PNmzfnpptuSpLMz89neno6a9euza5duy4//9ixY7l48WJuueWWrF+/Pkly+vTpnDlzJlu3bs22bduSJHNzczl+/HjWrVuXHTt2XH7+0aNHc+nSpezcuTM33ND7az516lTOnTuXqampy8OiZ2dnc/LkyWzcuDE333zz5ecfOXIkSfLXf/3XT2jELJqZmcmtt9467F8VjRiXf3uTmKflPqa3ve1t8gowhlb7+WlSjmnR7t27J+aYJvH35Jgc08mTJy9vPynHNIm/J8fkmKanpy8/b/E1JuGYlvo9Pf41r9Uomqfb+rdXuxR/8fFtT7oVH+fx/5iZXLfffnvXJTACx48f77oEAPo+7/M+r+sSGLENGzbkKU8ZxYVzwHLauHFj5ufnP+5LD2A8rVmzJk996lO7LmPsrVlYWLiuFyilvDPJS5L8m1rrHz7Jdvck+fok31Rr/ZXr2unHu74DGHOHDh3K/v37l3z8wIEDueOOO1awImAp8goAAABjbc21PmEUX91+pH+76SrbPa1/e3oE+1w19u3bl6mpqYGPTU1NZd++fStcEbAUeQUAAIDJMorm6SP9251X2W7x8UeedCs+zoYNG3Lw4MEnNGQWV+/esGFDR5UBV5JXAAAAmCyjmPP0ff3b5y61QSllY5JnJbmU5AMj2Oeqsnfv3hw+fDj33HNPHn744XzmZ35m9u3bpxEDY0heoS2DJqUHxpO8QhtkFdohr8MZxZynn5rkfyc5k2RHrXV2wDZfneTXk7yn1vq517XDJ5roOU8BAAAAgJFY+TlPa61/l+RdSbYm+d4rHy+lbEjyQ4ubX+/+AAAAAABWwigu20+S1yb5kyQ/WEo5l+SNtda5UsotSd6U3iX7H0py94j293jX3DFuVSnl/iSptX5O17UAT05eoQ2yCu2QV2iDrEI75HU4o1gwKrXWP0vyyv7r/XSSR0opR5NMJ3lZkmNJvrjW+tgo9gcAAAAAsNxG0jxNklrr3UlemOT3kzyW5Jb0mqdvSPLZtdajo9oXAAAAAMByG9Vl+0mSWuu7k7x7lK8JAAAAANCFkY08BQAAAACYJJqnAAAAAAADaJ4CAAAAAAygeQoAAAAAMIDmKQAAAADAAJqnAAAAAAADaJ4CAAAAAAywZmFhoesaAAAAAADGjpGnAAAAAAADaJ4CAAAAAAygeQoAAAAAMIDmKQAAAADAAJqnAAAAAAADaJ4CAAAAAAygeQoAAAAAMIDmKQAAAADAADd0XQBXV0p5QZLvT/IFSbYkeSjJ7yS5q9b6SJe1Af+klLI1yf4kX5nkmUkuJvnbJG9O8ku11ksdlgc8iVLKlyZ5U5KFJF9Za/3zjksC+kopO5N8T5KXJdmR3vn1fyX5pSS/Xmu90GF5QJJSypokX5Pkm5J8VpKtSU4l+ZMkb6y1/mmH5cGqVkr5jCS/mOTTk7ys1vqXA7Z5VpLXJnlJkk9McjLJHyT5sVrr0RUsdywZeTrmSilfl+RPk9yRZEOSh5PsSq9Bc38pZUeH5QF9pZRPSfL+JD+U5NYkjyS5Mcnzk9Qkf1hKWd9dhcBS+vl9a5Kbkzw9vQ9+wBgopXxhkg8k+bb03gOfTHIpvUEFb07y/lLKJ3dXIVBKWZfkd5P8WpIvSrI5yYkk29NrqL67lPLa7iqE1auU8vIkf5nk89Nrin7JgG1uT/K+JF+X3hcfH04vv9+c5K9KKc9eqXrHlebpGCulPDfJW9IbBfPdSbbVWncmeUaSe9N7A/mOUooRxNChUsraJL+dXib/OMnuflY3J/nXSY6n9w3ej3RWJDBQKeUp6TVgNiX5/f7dG7urCFhUSnlGeufXLUl+PMlNtdZd6X34+8IkH0zyaUle01WNQJLkB5J8aXpfbnxZkk3998JPS/Kd6X3h8WP9L0OAFVBKubGU8t+S/Gp6g3o+0H9o7RXb7UpyKMn6JD+VZKp/rn16/7n/Ir2BQJ+wUrWPI83T8XZXelMrvL7W+rO11rkkqbU+lOQr0rsc+NlJvra7EoEkL07yGel9Q3dHrfUfkqTWulBrvTfJN/a3+0/9Rg0wPr41vRFsv57ktzquBfh4r0+vcfrTtdbX1FrPJEmt9WO11vuSfG6S16U3chzozuJ73VfWWg/VWj+WJLXWC7XWN6TXkEmSV3ZSHaxOdyV5VZKjSV6Y5G1LbPfa9Ab9/Eqt9ftqrR9NklrrTJJXJLkvvUbqty93wePMh/gxVUrZk94lDx9J8tNXPl5rPZ/eG8ok+ZYVLA14oj3927fWWmcHPH5fktkkn5De5Q/AGCilPDO90Wyn0rskGBgTpZQtSb46ydkkPzpom1rrbK31R8ylCJ1bfH/7Z0s8vnj/zStQC9Dz7iQ/k+Q5tda/GLRBKWVjel9+fCy96ec+Tv+LkMUpN76lP7fxqqR5Or5u79++Y4lmTNIbWj2X5LmllKetSFXAIIeSHOj/GWQhvRNSkjy2IhUBT6r/5u9N6V2i/239b9eB8fFFSdYl+YNa69muiwGe1P392xcs8fji/e9dgVqAJP1R4N9Ta/3Ik2z2gvTOtX/ev8J5kL9Ib9Hypyf5VyMusxnmyhxft/VvlzzB1FpnSykfTPKcJHuz9Dd9wDKqtT6c5LueZJPnpXcpxIc0aGBsfH2SlyZ5e5Lf7LgW4Ik+s3/73v6UN/8uvYVn9iQ5neQ9SX5hcaocoFP/Ob15/99SSnllel96XCqlPDW9BWe+L8mx9EbBAeNjmL7TQinlvUn+ZX/7v1uJwsaNkafj6xP7t0t1/xdNX7E9MEb6H/h+ov/jj3dZC9BTStma3ge42SSvqrUudFwS8ESf0r89kd6XHL+R3pz/e9O7Qut7k3ywlPL1nVQHXNafOuPFSY4k+b0kp0sp/5DeFHT/pX/f59daT3VXJTCAvtOQNE/H17b+7Uevst3i49uedCugK69J8qL0VvG+p+NagJ7XJ/mkJD9Ua52+2sZAJ7b0b78rvUv4X5/kmelNtbE3yVuSbEhvpNtSlwoDK2dH/im3W5I8I73Vu5PevP+rtukCY0zfaUgu258cq3biXhhXpZQvT+/D3v9N8gqj26B7pZRnJ3l1kvenNxoGGE8b+7fPSfJ1tda3Pu6xDyR5RSnlTJLvSG9F4S9c4fqAvlLK/iQ/m95I029N8jtJHknvC4//kGR/kj8rpbzUAm/QtFXbd9I8HV+Lk/puusp2iwtFnV7GWoBrVEq5LcmvpXdZ8JfVWh/puCRY9fqLRP1celfevLrWOt9xScDSLvRvH7iicfp4P5rkVUleXEqZMq84rLxSyjOT/GSS80leWGv9m8c9/KEk31NK+UCSX0ny5lLKp/dX8Aa6p+80JJftj6/FRsvOq2y3+LjGDIyJUsrO9OZ2Wp/ka2qtD3RcEtDzkvRGp91Ta7XIIoy3xQ90S2a1/8Xk3/d/3LXsFQGDfHWSG5PcfUXj9PHuTvK36a3U/byVKgy4Kn2nIRl5Or7e17997lIblFI2JnlWkkvpXb4EdKyUsiW9+U1vTvKdtda3d1wS8E++rH+7r5TyfwY8vjhX25f3H//7JF9Ra70wYFtgeS1m9Goj1B4bcjtgeTyzf/vBpTbor9b9wSSfnt5cqH++AnUBVzdM32lNks+5YvtVx8jT8fWu/u3LSilLDaH+0vRGtr2v1np2RaoCllRKuSHJryd5dpJfiPkUYdz8QXrfmH9Skj0D/tzU325T/+fPiC+aoSuL8yJ+zlIb9AcSfEr/R4u/QTcWp8v4l1fZbnHk2sllrAW4Nn+WZD7J80spS2X4c9PL7/9LbwT5quQDwZiqtf5dKeVdSW5P8r1JXvf4x0spG5L80OLmK1kb8ET9b+TekOSLk9yb5NstEAXjpdb6jiRTSz1eSnl5kl9N8j9qrS9fscKAQQ6n90Htef1FZt45YJuS3pcdh80tDp05nOQ16S3i9jO11ic0R0spL05yW5JzSd67wvUBS6i1frSUck+SV6Q3j/grHv94KeUpSX6s/+ObVvPnWyNPx9tr07sk/wdLKd9dSlmfJKWUW5L8VnqX7H8ovTlkgG69qv/nQ0m+ykI0APDPV2udS/L6/o+/VUr5hlLKjUlvxGkp5buS/FSShVwxyABYUe9M7zL8m5LcV0q5vd9wSSllQynlFUl+u7/tT7piEsbOj6a3yPE3llJ+qpTytCQppWxL8t+TvDTJqSQHuiuxe2sWFlZt47gJpZR/n+Qt/R9n07vccEd6je9jSb6g1nq0o/KAJP2pNWaSbOjfLjX6ZSG9b+xW9YkHxpWRpzBe+ld1/GKS/9i/69H0RqPenN7UVfNJXl1rfVM3FQJJUkq5Ob2pcT6rf9fZ9Fblvjm998dJ8l+TfMdqHrkGXSqlvC7JDye5q9b6A1c89tIkb0+yLslckhNJPjm9xeD+McmLa61/taIFjxkjT8dcrfXuJC9MbwGax5Lckt6cTm9I8tkapzAWHkvy/v5/TyX5tCX+LE6SD4ynv4lLCmFs1FoXaq0lyb9Nb0qcjyZ5epKHk7w5yW0ap9C9WuuJJM9L8uok705yMb3Gy6kkb01ye63VlFbQrfekNyDvPVc+0J8a57Ykv5Helx870svvLyf5rNXeOE2MPAUAAAAAGMjIUwAAAACAATRPAQAAAAAG0DwFAAAAABhA8xQAAAAAYADNUwAAAACAATRPAQAAAAAG0DwFAAAAABhA8xQAAAAAYADNUwAAAACAATRPAQAAAAAG0DwFAAAAABhA8xQAAG1NsCkAAAA7SURBVAAAYADNUwAAAACAATRPAQAAAAAG0DwFAAAAABhA8xQAAAAAYADNUwAAAACAATRPAQAAAAAG+P8jEUnWUEa9aAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 864x80.64 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 98,
       "width": 679
      },
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "figure, axes = ts.plot()\n",
    "figure.savefig(\"test.pdf\", bbox_inches=\"tight\", format=\"pdf\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}


================================================
FILE: examples/Shaded.ipynb
================================================
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import traces\n",
    "from datetime import datetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "%config InlineBackend.figure_format = 'retina'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "ts = traces.TimeSeries(data=[\n",
    "    (datetime(2016, 9, 27, 23, 0, 0), 30),\n",
    "    (datetime(2016, 9, 27, 23, 0, 5), 33),\n",
    "    (datetime(2016, 9, 27, 23, 0, 10), 33),\n",
    "    (datetime(2016, 9, 27, 23, 0, 15), 34),\n",
    "    (datetime(2016, 9, 27, 23, 0, 31), 25),\n",
    "    (datetime(2016, 9, 27, 23, 0, 45), 30),\n",
    "    (datetime(2016, 9, 27, 23, 0, 45), 38),\n",
    "    (datetime(2016, 9, 27, 23, 1, 45), 33),\n",
    "    (datetime(2016, 9, 27, 23, 1, 55), 24),\n",
    "    (datetime(2016, 9, 27, 23, 2, 15), 24),\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(datetime.datetime(2016, 9, 27, 23, 0, 5),\n",
       "  datetime.datetime(2016, 9, 27, 23, 0, 31))]"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inrange = traces.TimeSeries(default=False)\n",
    "for t, v in ts:\n",
    "    inrange[t] = (31 < v < 35)\n",
    "    \n",
    "inrange.compact()\n",
    "\n",
    "intervals_in_range = []\n",
    "for t0, t1, value in inrange.iterperiods(value=True):\n",
    "    if (t1 - t0).total_seconds() > 20:\n",
    "        intervals_in_range.append((t0, t1))\n",
    "        \n",
    "intervals_in_range"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x149.76 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 148,
       "width": 687
      },
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.dates as mdates\n",
    "fig, ax = ts.plot()\n",
    "ax.fill_between([ts.first_key(), ts.last_key()], 31, 35, color=\"#eee\")\n",
    "ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}


================================================
FILE: examples/Untitled.ipynb
================================================
{
 "cells": [],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 4
}


================================================
FILE: examples/data/lightbulb-01.csv
================================================
time,watts
2016-01-01T06:31:41,45
2016-01-01T07:04:42,0
2016-01-01T07:09:25,45
2016-01-01T07:12:56,0
2016-01-01T07:47:46,45
2016-01-01T08:07:35,0
2016-01-01T08:51:59,45
2016-01-01T08:53:45,0
2016-01-01T09:06:38,45
2016-01-01T09:24:44,0
2016-01-01T09:31:05,45
2016-01-01T09:33:30,0
2016-01-01T10:15:18,45
2016-01-01T10:32:19,0
2016-01-01T10:43:41,45
2016-01-01T10:46:10,0
2016-01-01T10:55:48,45
2016-01-01T11:13:47,0
2016-01-01T11:14:36,45
2016-01-01T11:20:39,0
2016-01-01T11:26:01,45
2016-01-01T11:27:09,0
2016-01-01T12:24:46,45
2016-01-01T12:31:48,0
2016-01-01T13:35:49,45
2016-01-01T13:50:07,0
2016-01-01T14:54:08,45
2016-01-01T14:54:19,0
2016-01-01T15:14:09,45
2016-01-01T15:26:54,0
2016-01-01T15:37:23,45
2016-01-01T15:39:22,0
2016-01-01T15:57:24,45
2016-01-01T16:08:36,0
2016-01-01T16:30:58,45
2016-01-01T16:49:46,0
2016-01-01T17:34:19,45
2016-01-01T17:36:05,0
2016-01-01T17:58:03,45
2016-01-01T18:27:57,0
2016-01-01T19:23:06,45
2016-01-01T19:30:38,0
2016-01-02T09:43:54,45
2016-01-02T09:53:07,0
2016-01-02T10:05:19,45
2016-01-02T10:10:25,0
2016-01-02T10:50:42,45
2016-01-02T10:56:38,0
2016-01-02T14:31:00,45
2016-01-02T14:38:12,0
2016-01-02T14:55:03,45
2016-01-02T15:38:02,0
2016-01-02T16:00:52,45
2016-01-02T16:03:51,0
2016-01-02T18:46:15,45
2016-01-02T19:03:52,0
2016-01-03T17:03:28,45
2016-01-03T17:10:14,0
2016-01-04T07:36:58,45
2016-01-04T07:39:34,0
2016-01-04T07:44:47,45
2016-01-04T07:57:45,0
2016-01-04T08:06:30,45
2016-01-04T08:10:27,0
2016-01-04T10:15:09,45
2016-01-04T10:24:10,0
2016-01-04T10:47:37,45
2016-01-04T10:49:54,0
2016-01-04T11:15:53,45
2016-01-04T11:27:10,0
2016-01-04T11:52:13,45
2016-01-04T12:35:32,0
2016-01-04T14:02:48,45
2016-01-04T14:06:41,0
2016-01-04T14:21:12,45
2016-01-04T14:25:59,0
2016-01-04T14:48:02,45
2016-01-04T15:01:27,0
2016-01-04T15:08:08,45
2016-01-04T15:10:18,0
2016-01-04T16:01:41,45
2016-01-04T17:00:20,0
2016-01-04T17:59:22,45
2016-01-04T18:07:01,0
2016-01-04T20:18:49,45
2016-01-04T20:44:56,0
2016-01-05T09:38:31,45
2016-01-05T10:04:40,0
2016-01-05T10:05:36,45
2016-01-05T10:09:45,0
2016-01-05T10:36:43,45
2016-01-05T11:37:10,0
2016-01-05T13:06:01,45
2016-01-05T13:24:03,0
2016-01-05T13:38:10,45
2016-01-05T13:40:52,0
2016-01-05T13:43:38,45
2016-01-05T13:47:13,0
2016-01-05T14:30:41,45
2016-01-05T14:39:27,0
2016-01-05T14:59:14,45
2016-01-05T15:49:53,0
2016-01-05T16:17:59,45
2016-01-05T16:37:36,0
2016-01-05T17:08:06,45
2016-01-05T17:10:08,0
2016-01-05T17:19:42,45
2016-01-05T17:29:09,0
2016-01-05T17:33:26,45
2016-01-05T17:37:27,0
2016-01-05T17:56:28,45
2016-01-05T18:02:04,0
2016-01-05T18:23:12,45
2016-01-05T18:56:04,0
2016-01-05T19:03:26,45
2016-01-05T19:14:02,0
2016-01-05T20:28:46,45
2016-01-05T20:54:16,0
2016-01-06T09:32:17,45
2016-01-06T09:33:01,0
2016-01-06T09:37:59,45
2016-01-06T09:43:26,0
2016-01-06T09:56:08,45
2016-01-06T09:58:33,0
2016-01-06T10:12:48,45
2016-01-06T12:19:11,0
2016-01-06T12:30:02,45
2016-01-06T12:36:09,0
2016-01-06T12:44:37,45
2016-01-06T13:16:20,0
2016-01-06T13:33:44,45
2016-01-06T13:36:15,0
2016-01-06T13:45:46,45
2016-01-06T13:58:21,0
2016-01-06T14:07:29,45
2016-01-06T15:05:52,0
2016-01-06T15:10:51,45
2016-01-06T15:48:25,0
2016-01-06T15:49:11,45
2016-01-06T16:24:58,0
2016-01-06T16:28:27,45
2016-01-06T16:39:16,0
2016-01-06T16:48:42,45
2016-01-06T16:58:06,0
2016-01-06T17:03:00,45
2016-01-06T17:33:34,0
2016-01-06T17:39:25,45
2016-01-06T17:40:42,0
2016-01-07T07:52:18,45
2016-01-07T07:54:04,0
2016-01-07T08:12:04,45
2016-01-07T08:18:26,0
2016-01-07T08:20:26,45
2016-01-07T08:38:41,0
2016-01-07T08:39:41,45
2016-01-07T09:36:15,0
2016-01-07T09:52:50,45
2016-01-07T10:09:46,0
2016-01-07T10:18:38,45
2016-01-07T10:26:59,0
2016-01-07T10:54:47,45
2016-01-07T11:05:06,0
2016-01-07T11:16:20,45
2016-01-07T11:28:34,0
2016-01-07T11:32:55,45
2016-01-07T12:46:13,0
2016-01-07T12:52:15,45
2016-01-07T12:59:12,0
2016-01-07T13:18:02,45
2016-01-07T13:27:43,0
2016-01-07T13:37:45,45
2016-01-07T13:55:58,0
2016-01-07T14:27:08,45
2016-01-07T14:32:33,0
2016-01-07T14:34:56,45
2016-01-07T14:45:07,0
2016-01-07T14:47:39,45
2016-01-07T14:54:29,0
2016-01-07T16:09:51,45
2016-01-07T16:49:30,0
2016-01-07T17:07:51,45
2016-01-07T17:08:01,0
2016-01-07T17:17:12,45
2016-01-07T17:40:29,0
2016-01-07T17:41:45,45
2016-01-07T18:35:42,0
2016-01-07T19:32:54,45
2016-01-07T19:58:26,0
2016-01-07T20:20:16,45
2016-01-07T20:23:30,0
2016-01-08T09:17:10,45
2016-01-08T09:25:43,0
2016-01-08T10:10:58,45
2016-01-08T10:19:17,0
2016-01-08T11:13:33,45
2016-01-08T11:13:37,0
2016-01-08T11:17:33,45
2016-01-08T11:23:49,0
2016-01-08T11:32:15,45
2016-01-08T11:37:58,0
2016-01-08T12:57:21,45
2016-01-08T13:18:28,0
2016-01-08T14:57:37,45
2016-01-08T15:16:29,0
2016-01-08T15:32:04,45
2016-01-08T15:54:17,0
2016-01-08T16:57:18,45
2016-01-08T17:04:23,0
2016-01-08T17:14:24,45
2016-01-08T17:23:55,0
2016-01-08T17:40:30,45
2016-01-08T17:47:26,0
2016-01-09T09:56:14,45
2016-01-09T09:56:46,0
2016-01-09T13:24:08,45
2016-01-09T14:02:04,0
2016-01-09T14:02:50,45
2016-01-09T14:07:08,0
2016-01-09T15:38:20,45
2016-01-09T15:48:48,0
2016-01-09T17:22:47,45
2016-01-09T17:51:51,0
2016-01-09T18:35:19,45
2016-01-09T18:49:02,0
2016-01-11T08:19:06,45
2016-01-11T08:33:00,0
2016-01-11T08:39:01,45
2016-01-11T09:31:45,0
2016-01-11T09:32:49,45
2016-01-11T09:40:29,0
2016-01-11T10:26:04,45
2016-01-11T10:55:21,0
2016-01-11T11:11:57,45
2016-01-11T11:17:13,0
2016-01-11T11:24:03,45
2016-01-11T11:54:24,0
2016-01-11T12:03:03,45
2016-01-11T12:09:57,0
2016-01-11T12:14:20,45
2016-01-11T12:17:55,0
2016-01-11T13:41:24,45
2016-01-11T14:20:39,0
2016-01-11T14:23:11,45
2016-01-11T14:42:48,0
2016-01-11T14:44:35,45
2016-01-11T15:07:02,0
2016-01-11T15:19:54,45
2016-01-11T15:22:25,0
2016-01-11T15:26:43,45
2016-01-11T16:03:25,0
2016-01-11T16:21:21,45
2016-01-11T16:28:32,0
2016-01-11T16:32:53,45
2016-01-11T16:46:26,0
2016-01-11T17:02:29,45
2016-01-11T19:35:41,0
2016-01-12T09:07:25,45
2016-01-12T09:15:03,0
2016-01-12T09:38:15,45
2016-01-12T11:17:26,0
2016-01-12T11:42:56,45
2016-01-12T11:51:42,0
2016-01-12T12:24:12,45
2016-01-12T12:33:56,0
2016-01-12T13:21:40,45
2016-01-12T13:48:30,0
2016-01-12T14:11:39,45
2016-01-12T14:13:36,0
2016-01-12T14:45:51,45
2016-01-12T16:11:03,0
2016-01-12T16:19:12,45
2016-01-12T16:43:05,0
2016-01-12T16:58:55,45
2016-01-12T17:40:45,0
2016-01-12T18:02:29,45
2016-01-12T18:04:47,0
2016-01-13T07:38:16,45
2016-01-13T07:42:34,0
2016-01-13T08:12:43,45
2016-01-13T08:49:53,0
2016-01-13T09:53:23,45
2016-01-13T10:17:45,0
2016-01-13T10:37:37,45
2016-01-13T11:07:32,0
2016-01-13T12:49:45,45
2016-01-13T12:51:51,0
2016-01-13T13:21:52,45
2016-01-13T13:23:52,0
2016-01-13T14:10:55,45
2016-01-13T14:17:34,0
2016-01-13T14:19:07,45
2016-01-13T15:18:38,0
2016-01-13T15:25:03,45
2016-01-13T16:06:56,0
2016-01-13T16:09:54,45
2016-01-13T16:13:35,0
2016-01-13T16:21:58,45
2016-01-13T16:54:26,0
2016-01-13T18:40:10,45
2016-01-13T18:46:48,0
2016-01-14T07:59:01,45
2016-01-14T09:00:58,0
2016-01-14T09:24:29,45
2016-01-14T09:29:17,0
2016-01-14T09:40:06,45
2016-01-14T09:45:35,0
2016-01-14T10:13:24,45
2016-01-14T10:18:23,0
2016-01-14T10:52:19,45
2016-01-14T10:55:39,0
2016-01-14T13:05:05,45
2016-01-14T13:10:17,0
2016-01-14T13:15:03,45
2016-01-14T13:34:11,0
2016-01-14T13:36:50,45
2016-01-14T14:11:07,0
2016-01-14T14:29:34,45
2016-01-14T14:31:52,0
2016-01-14T14:34:24,45
2016-01-14T14:37:31,0
2016-01-14T14:47:07,45
2016-01-14T14:57:07,0
2016-01-14T15:01:19,45
2016-01-14T15:03:40,0
2016-01-14T15:15:16,45
2016-01-14T17:25:52,0
2016-01-14T17:36:24,45
2016-01-14T17:42:50,0
2016-01-14T17:53:06,45
2016-01-14T18:24:50,0
2016-01-14T18:51:10,45
2016-01-14T19:20:43,0
2016-01-14T19:56:17,45
2016-01-14T19:59:37,0
2016-01-15T08:01:54,45
2016-01-15T08:27:45,0
2016-01-15T09:45:08,45
2016-01-15T10:15:10,0
2016-01-15T10:18:42,45
2016-01-15T10:53:48,0
2016-01-15T11:02:13,45
2016-01-15T11:24:01,0
2016-01-15T12:20:34,45
2016-01-15T12:29:49,0
2016-01-15T13:18:08,45
2016-01-15T13:19:14,0
2016-01-15T13:20:41,45
2016-01-15T13:25:52,0
2016-01-15T14:15:38,45
2016-01-15T14:27:40,0
2016-01-15T14:29:16,45
2016-01-15T14:30:14,0
2016-01-15T14:48:54,45
2016-01-15T15:33:13,0
2016-01-15T15:38:39,45
2016-01-15T15:49:35,0
2016-01-15T15:53:52,45
2016-01-15T16:13:09,0
2016-01-15T16:38:22,45
2016-01-15T17:16:46,0
2016-01-15T17:30:25,45
2016-01-15T17:50:08,0
2016-01-16T08:34:15,45
2016-01-16T08:51:47,0
2016-01-16T10:03:53,45
2016-01-16T10:05:14,0
2016-01-16T12:57:08,45
2016-01-16T13:01:54,0
2016-01-17T10:10:04,45
2016-01-17T10:35:25,0
2016-01-18T07:36:58,45
2016-01-18T07:37:44,0
2016-01-18T08:23:25,45
2016-01-18T08:29:04,0
2016-01-18T09:20:56,45
2016-01-18T09:23:17,0
2016-01-18T10:06:37,45
2016-01-18T10:24:45,0
2016-01-18T10:29:06,45
2016-01-18T10:54:23,0
2016-01-18T10:59:44,45
2016-01-18T11:12:30,0
2016-01-18T11:17:19,45
2016-01-18T11:31:06,0
2016-01-18T11:39:05,45
2016-01-18T11:50:57,0
2016-01-18T12:10:00,45
2016-01-18T12:27:22,0
2016-01-18T12:47:07,45
2016-01-18T12:48:35,0
2016-01-18T13:03:28,45
2016-01-18T13:19:30,0
2016-01-18T13:31:00,45
2016-01-18T13:42:38,0
2016-01-18T13:57:56,45
2016-01-18T14:52:47,0
2016-01-18T15:26:39,45
2016-01-18T16:08:19,0
2016-01-18T16:39:21,45
2016-01-18T17:37:24,0
2016-01-18T18:11:16,45
2016-01-18T18:19:40,0
2016-01-18T18:49:11,45
2016-01-18T18:50:10,0
2016-01-18T18:53:57,45
2016-01-18T18:56:50,0
2016-01-18T19:13:39,45
2016-01-18T19:16:29,0
2016-01-18T19:35:18,45
2016-01-18T19:40:47,0
2016-01-19T07:38:54,45
2016-01-19T07:40:26,0
2016-01-19T08:10:22,45
2016-01-19T08:33:19,0
2016-01-19T08:50:32,45
2016-01-19T08:52:31,0
2016-01-19T09:31:18,45
2016-01-19T09:35:59,0
2016-01-19T09:55:23,45
2016-01-19T10:24:57,0
2016-01-19T10:25:02,45
2016-01-19T10:29:42,0
2016-01-19T10:44:23,45
2016-01-19T11:03:00,0
2016-01-19T11:27:41,45
2016-01-19T11:43:47,0
2016-01-19T12:12:02,45
2016-01-19T12:17:12,0
2016-01-19T12:24:02,45
2016-01-19T12:30:30,0
2016-01-19T13:19:54,45
2016-01-19T13:21:55,0
2016-01-19T14:01:43,45
2016-01-19T15:47:04,0
2016-01-19T15:52:16,45
2016-01-19T16:57:52,0
2016-01-19T17:04:06,45
2016-01-19T17:05:38,0
2016-01-19T17:16:03,45
2016-01-19T17:28:18,0
2016-01-19T18:11:52,45
2016-01-19T18:32:56,0
2016-01-20T08:56:12,45
2016-01-20T09:06:57,0
2016-01-20T09:09:53,45
2016-01-20T09:12:51,0
2016-01-20T09:25:24,45
2016-01-20T10:10:00,0
2016-01-20T10:18:15,45
2016-01-20T10:51:43,0
2016-01-20T10:59:38,45
2016-01-20T11:05:20,0
2016-01-20T11:17:57,45
2016-01-20T11:28:53,0
2016-01-20T11:40:47,45
2016-01-20T12:06:02,0
2016-01-20T12:19:30,45
2016-01-20T12:34:18,0
2016-01-20T12:41:27,45
2016-01-20T12:48:12,0
2016-01-20T13:39:11,45
2016-01-20T13:49:41,0
2016-01-20T13:59:06,45
2016-01-20T14:23:04,0
2016-01-20T14:39:12,45
2016-01-20T14:40:42,0
2016-01-20T14:40:44,45
2016-01-20T15:12:50,0
2016-01-20T15:13:54,45
2016-01-20T15:21:27,0
2016-01-20T17:01:50,45
2016-01-20T17:43:11,0
2016-01-20T17:58:36,45
2016-01-20T18:04:45,0
2016-01-20T18:13:30,45
2016-01-20T18:40:46,0
2016-01-20T19:13:30,45
2016-01-20T19:15:31,0
2016-01-21T07:56:13,45
2016-01-21T08:14:59,0
2016-01-21T09:44:22,45
2016-01-21T09:45:02,0
2016-01-21T09:46:23,45
2016-01-21T10:02:28,0
2016-01-21T10:15:21,45
2016-01-21T10:18:18,0
2016-01-21T10:31:42,45
2016-01-21T10:58:30,0
2016-01-21T11:05:03,45
2016-01-21T11:05:32,0
2016-01-21T11:08:07,45
2016-01-21T11:23:05,0
2016-01-21T11:23:22,45
2016-01-21T12:05:42,0
2016-01-21T13:14:54,45
2016-01-21T13:20:28,0
2016-01-21T13:27:30,45
2016-01-21T14:25:13,0
2016-01-21T14:51:22,45
2016-01-21T16:29:39,0
2016-01-21T16:35:46,45
2016-01-21T16:41:19,0
2016-01-21T16:55:31,45
2016-01-21T17:49:29,0
2016-01-22T07:09:17,45
2016-01-22T07:12:50,0
2016-01-22T08:18:42,45
2016-01-22T08:26:05,0
2016-01-22T08:31:16,45
2016-01-22T09:00:24,0
2016-01-22T09:12:06,45
2016-01-22T09:38:11,0
2016-01-22T09:41:24,45
2016-01-22T09:54:45,0
2016-01-22T10:37:15,45
2016-01-22T10:37:20,0
2016-01-22T10:46:34,45
2016-01-22T11:11:18,0
2016-01-22T12:15:12,45
2016-01-22T12:16:42,0
2016-01-22T12:18:36,45
2016-01-22T12:20:24,0
2016-01-22T12:23:17,45
2016-01-22T12:38:29,0
2016-01-22T13:31:22,45
2016-01-22T13:40:05,0
2016-01-22T13:44:15,45
2016-01-22T14:48:24,0
2016-01-22T15:57:31,45
2016-01-22T16:01:15,0
2016-01-22T16:38:17,45
2016-01-22T16:47:40,0
2016-01-22T17:17:28,45
2016-01-22T17:19:53,0
2016-01-22T17:32:14,45
2016-01-22T17:40:12,0
2016-01-22T18:13:47,45
2016-01-22T18:22:58,0
2016-01-22T18:37:52,45
2016-01-22T18:51:19,0
2016-01-23T09:20:44,45
2016-01-23T09:24:51,0
2016-01-23T09:46:40,45
2016-01-23T09:46:41,0
2016-01-23T10:21:49,45
2016-01-23T10:44:15,0
2016-01-23T11:29:32,45
2016-01-23T11:51:24,0
2016-01-23T13:02:58,45
2016-01-23T13:57:57,0
2016-01-23T15:22:59,45
2016-01-23T15:31:53,0
2016-01-23T16:55:20,45
2016-01-23T17:04:35,0
2016-01-24T13:17:28,45
2016-01-24T13:29:59,0
2016-01-25T08:50:54,45
2016-01-25T08:57:29,0
2016-01-25T09:08:22,45
2016-01-25T09:13:29,0
2016-01-25T09:22:52,45
2016-01-25T09:28:16,0
2016-01-25T09:29:18,45
2016-01-25T10:32:49,0
2016-01-25T10:54:16,45
2016-01-25T11:00:36,0
2016-01-25T11:28:32,45
2016-01-25T11:55:34,0
2016-01-25T12:53:35,45
2016-01-25T13:03:01,0
2016-01-25T13:14:44,45
2016-01-25T13:51:04,0
2016-01-25T14:04:32,45
2016-01-25T14:59:57,0
2016-01-25T15:10:46,45
2016-01-25T15:13:04,0
2016-01-25T15:32:43,45
2016-01-25T15:41:11,0
2016-01-25T16:00:13,45
2016-01-25T16:31:42,0
2016-01-25T16:46:55,45
2016-01-25T16:47:38,0
2016-01-25T16:53:09,45
2016-01-25T16:59:30,0
2016-01-26T08:18:18,45
2016-01-26T11:20:43,0
2016-01-26T11:23:51,45
2016-01-26T11:24:25,0
2016-01-26T11:40:35,45
2016-01-26T12:18:14,0
2016-01-26T12:26:21,45
2016-01-26T12:26:53,0
2016-01-26T13:04:00,45
2016-01-26T13:04:45,0
2016-01-26T13:14:47,45
2016-01-26T13:19:55,0
2016-01-26T13:38:25,45
2016-01-26T14:03:41,0
2016-01-26T14:21:40,45
2016-01-26T15:09:52,0
2016-01-26T15:13:30,45
2016-01-26T15:48:55,0
2016-01-26T16:30:23,45
2016-01-26T18:55:04,0
2016-01-26T19:16:28,45
2016-01-26T19:28:40,0
2016-01-26T19:50:35,45
2016-01-26T20:20:24,0
2016-01-27T08:11:55,45
2016-01-27T08:15:13,0
2016-01-27T09:07:39,45
2016-01-27T09:09:52,0
2016-01-27T09:17:10,45
2016-01-27T10:58:05,0
2016-01-27T11:12:35,45
2016-01-27T11:25:55,0
2016-01-27T12:02:21,45
2016-01-27T12:03:19,0
2016-01-27T13:01:27,45
2016-01-27T13:02:32,0
2016-01-27T13:40:22,45
2016-01-27T13:44:25,0
2016-01-27T14:00:40,45
2016-01-27T15:14:33,0
2016-01-27T15:19:05,45
2016-01-27T15:37:28,0
2016-01-27T15:39:10,45
2016-01-27T15:40:58,0
2016-01-27T15:56:45,45
2016-01-27T16:00:31,0
2016-01-27T16:23:00,45
2016-01-27T16:27:44,0
2016-01-27T17:35:19,45
2016-01-27T18:02:02,0
2016-01-27T18:16:58,45
2016-01-27T18:25:01,0
2016-01-27T19:19:40,45
2016-01-27T20:04:33,0
2016-01-27T20:29:28,45
2016-01-27T20:40:49,0
2016-01-28T06:46:55,45
2016-01-28T07:10:50,0
2016-01-28T07:49:52,45
2016-01-28T07:50:35,0
2016-01-28T09:45:20,45
2016-01-28T09:52:57,0
2016-01-28T10:18:53,45
2016-01-28T10:47:58,0
2016-01-28T11:58:47,45
2016-01-28T12:10:49,0
2016-01-28T12:52:14,45
2016-01-28T12:59:25,0
2016-01-28T13:25:10,45
2016-01-28T13:27:56,0
2016-01-28T13:47:06,45
2016-01-28T14:02:49,0
2016-01-28T14:09:49,45
2016-01-28T14:14:39,0
2016-01-28T14:22:43,45
2016-01-28T16:39:40,0
2016-01-28T16:39:55,45
2016-01-28T16:48:29,0
2016-01-28T17:23:13,45
2016-01-28T18:37:36,0
2016-01-28T18:54:51,45
2016-01-28T18:58:09,0
2016-01-29T08:19:47,45
2016-01-29T08:20:14,0
2016-01-29T08:40:47,45
2016-01-29T10:12:51,0
2016-01-29T10:45:55,45
2016-01-29T10:46:53,0
2016-01-29T11:03:55,45
2016-01-29T11:26:35,0
2016-01-29T11:38:56,45
2016-01-29T11:44:26,0
2016-01-29T11:54:53,45
2016-01-29T12:05:09,0
2016-01-29T12:39:15,45
2016-01-29T12:43:07,0
2016-01-29T13:19:16,45
2016-01-29T13:20:27,0
2016-01-29T13:26:32,45
2016-01-29T13:41:58,0
2016-01-29T13:59:06,45
2016-01-29T15:07:43,0
2016-01-29T15:44:53,45
2016-01-29T15:52:03,0
2016-01-29T16:15:48,45
2016-01-29T16:15:54,0
2016-01-29T16:51:51,45
2016-01-29T17:09:35,0
2016-01-29T17:11:30,45
2016-01-29T17:30:28,0
2016-01-29T17:51:30,45
2016-01-29T18:40:12,0
2016-01-30T10:27:10,45
2016-01-30T10:31:26,0
2016-01-30T11:06:57,45
2016-01-30T12:11:55,0
2016-01-30T19:43:27,45
2016-01-30T19:58:18,0
2016-02-01T07:58:09,45
2016-02-01T08:51:35,0
2016-02-01T09:00:37,45
2016-02-01T10:15:44,0
2016-02-01T10:22:16,45
2016-02-01T10:33:44,0
2016-02-01T10:49:06,45
2016-02-01T11:12:01,0
2016-02-01T11:32:18,45
2016-02-01T11:40:42,0
2016-02-01T11:57:05,45
2016-02-01T12:30:10,0
2016-02-01T12:35:09,45
2016-02-01T12:37:39,0
2016-02-01T12:50:53,45
2016-02-01T12:53:45,0
2016-02-01T13:47:14,45
2016-02-01T14:17:25,0
2016-02-01T14:38:49,45
2016-02-01T14:40:02,0
2016-02-01T15:08:29,45
2016-02-01T15:37:37,0
2016-02-01T15:42:29,45
2016-02-01T16:47:22,0
2016-02-01T17:03:52,45
2016-02-01T18:58:34,0
2016-02-01T20:06:28,45
2016-02-01T20:07:33,0
2016-02-02T10:11:37,45
2016-02-02T10:26:24,0
2016-02-02T10:31:17,45
2016-02-02T10:52:14,0
2016-02-02T10:52:26,45
2016-02-02T10:54:34,0
2016-02-02T11:23:42,45
2016-02-02T11:23:50,0
2016-02-02T11:58:13,45
2016-02-02T12:12:57,0
2016-02-02T12:29:50,45
2016-02-02T12:31:25,0
2016-02-02T13:09:23,45
2016-02-02T13:26:03,0
2016-02-02T13:41:44,45
2016-02-02T14:38:06,0
2016-02-02T14:44:03,45
2016-02-02T14:53:16,0
2016-02-02T14:54:50,45
2016-02-02T14:55:41,0
2016-02-02T14:58:29,45
2016-02-02T15:04:01,0
2016-02-02T15:07:23,45
2016-02-02T15:09:04,0
2016-02-02T15:12:19,45
2016-02-02T15:58:13,0
2016-02-02T16:09:04,45
2016-02-02T16:31:40,0
2016-02-02T16:33:44,45
2016-02-02T16:47:58,0
2016-02-02T18:01:53,45
2016-02-02T18:05:44,0
2016-02-02T18:41:50,45
2016-02-02T18:42:29,0
2016-02-03T09:11:05,45
2016-02-03T09:18:13,0
2016-02-03T09:26:40,45
2016-02-03T09:32:22,0
2016-02-03T09:33:59,45
2016-02-03T09:45:04,0
2016-02-03T09:52:21,45
2016-02-03T10:30:14,0
2016-02-03T10:33:14,45
2016-02-03T10:54:25,0
2016-02-03T10:58:37,45
2016-02-03T11:29:05,0
2016-02-03T11:41:08,45
2016-02-03T11:47:51,0
2016-02-03T11:53:07,45
2016-02-03T12:00:21,0
2016-02-03T13:00:53,45
2016-02-03T13:05:57,0
2016-02-03T13:11:39,45
2016-02-03T13:23:24,0
2016-02-03T13:25:46,45
2016-02-03T14:17:19,0
2016-02-03T15:01:44,45
2016-02-03T15:02:25,0
2016-02-03T15:08:42,45
2016-02-03T15:11:29,0
2016-02-03T15:26:34,45
2016-02-03T15:27:43,0
2016-02-03T15:42:34,45
2016-02-03T15:44:24,0
2016-02-03T16:21:12,45
2016-02-03T16:47:05,0
2016-02-03T16:56:49,45
2016-02-03T17:01:42,0
2016-02-03T17:04:59,45
2016-02-03T17:36:44,0
2016-02-04T08:53:42,45
2016-02-04T09:02:19,0
2016-02-04T09:43:44,45
2016-02-04T10:03:13,0
2016-02-04T10:03:34,45
2016-02-04T10:19:20,0
2016-02-04T10:58:46,45
2016-02-04T10:59:35,0
2016-02-04T11:36:31,45
2016-02-04T11:57:05,0
2016-02-04T12:35:41,45
2016-02-04T12:51:28,0
2016-02-04T12:54:47,45
2016-02-04T13:23:08,0
2016-02-04T13:36:16,45
2016-02-04T14:16:52,0
2016-02-04T14:41:15,45
2016-02-04T15:49:40,0
2016-02-04T16:17:11,45
2016-02-04T17:00:27,0
2016-02-04T17:01:41,45
2016-02-04T17:03:01,0
2016-02-04T17:19:19,45
2016-02-04T17:23:10,0
2016-02-04T18:03:09,45
2016-02-04T18:18:38,0
2016-02-04T18:59:11,45
2016-02-04T19:13:21,0
2016-02-05T07:50:01,45
2016-02-05T08:31:14,0
2016-02-05T08:47:53,45
2016-02-05T09:08:40,0
2016-02-05T09:22:51,45
2016-02-05T09:33:32,0
2016-02-05T09:35:11,45
2016-02-05T10:57:35,0
2016-02-05T11:21:30,45
2016-02-05T11:41:11,0
2016-02-05T12:33:19,45
2016-02-05T13:09:43,0
2016-02-05T13:11:07,45
2016-02-05T13:12:41,0
2016-02-05T13:21:57,45
2016-02-05T13:48:22,0
2016-02-05T13:58:29,45
2016-02-05T15:24:22,0
2016-02-05T16:10:11,45
2016-02-05T16:12:10,0
2016-02-05T16:19:14,45
2016-02-05T16:52:01,0
2016-02-05T16:56:58,45
2016-02-05T16:59:10,0
2016-02-05T17:44:55,45
2016-02-05T17:56:47,0
2016-02-06T10:12:10,45
2016-02-06T10:35:29,0
2016-02-06T15:48:42,45
2016-02-06T15:51:20,0
2016-02-08T07:44:41,45
2016-02-08T07:55:12,0
2016-02-08T08:22:58,45
2016-02-08T08:26:37,0
2016-02-08T09:20:56,45
2016-02-08T09:23:28,0
2016-02-08T09:29:46,45
2016-02-08T09:30:39,0
2016-02-08T10:54:47,45
2016-02-08T11:17:25,0
2016-02-08T11:38:46,45
2016-02-08T11:52:17,0
2016-02-08T11:52:21,45
2016-02-08T12:06:41,0
2016-02-08T12:50:23,45
2016-02-08T12:50:50,0
2016-02-08T13:13:44,45
2016-02-08T13:25:29,0
2016-02-08T13:50:10,45
2016-02-08T15:42:26,0
2016-02-08T15:45:01,45
2016-02-08T15:46:36,0
2016-02-08T15:53:13,45
2016-02-08T16:36:27,0
2016-02-08T16:39:30,45
2016-02-08T17:16:12,0
2016-02-09T08:06:00,45
2016-02-09T08:15:37,0
2016-02-09T09:01:48,45
2016-02-09T10:00:54,0
2016-02-09T10:30:41,45
2016-02-09T10:40:52,0
2016-02-09T10:54:50,45
2016-02-09T11:27:02,0
2016-02-09T11:27:22,45
2016-02-09T11:29:57,0
2016-02-09T12:07:40,45
2016-02-09T12:36:48,0
2016-02-09T12:59:13,45
2016-02-09T13:07:02,0
2016-02-09T14:46:20,45
2016-02-09T16:55:02,0
2016-02-09T17:10:48,45
2016-02-09T17:36:27,0
2016-02-09T17:52:46,45
2016-02-09T17:58:32,0
2016-02-09T18:11:49,45
2016-02-09T18:45:18,0
2016-02-10T08:59:01,45
2016-02-10T09:04:35,0
2016-02-10T09:14:24,45
2016-02-10T09:21:00,0
2016-02-10T09:50:14,45
2016-02-10T10:38:53,0
2016-02-10T10:47:20,45
2016-02-10T11:33:49,0
2016-02-10T12:25:37,45
2016-02-10T12:26:10,0
2016-02-10T12:45:16,45
2016-02-10T13:21:20,0
2016-02-10T14:04:09,45
2016-02-10T14:05:13,0
2016-02-10T14:05:27,45
2016-02-10T14:08:28,0
2016-02-10T14:16:09,45
2016-02-10T14:16:16,0
2016-02-10T14:37:53,45
2016-02-10T14:39:21,0
2016-02-10T14:41:03,45
2016-02-10T15:27:11,0
2016-02-10T15:31:43,45
2016-02-10T15:53:44,0
2016-02-10T15:57:45,45
2016-02-10T16:22:15,0
2016-02-10T16:22:45,45
2016-02-10T17:17:59,0
2016-02-10T17:33:16,45
2016-02-10T17:35:25,0
2016-02-10T18:21:36,45
2016-02-10T18:35:37,0
2016-02-11T09:19:37,45
2016-02-11T11:08:14,0
2016-02-11T11:14:26,45
2016-02-11T11:43:24,0
2016-02-11T11:46:00,45
2016-02-11T11:48:30,0
2016-02-11T12:39:26,45
2016-02-11T12:49:30,0
2016-02-11T12:52:31,45
2016-02-11T14:32:49,0
2016-02-11T15:28:42,45
2016-02-11T15:37:09,0
2016-02-11T15:51:33,45
2016-02-11T16:10:47,0
2016-02-11T16:12:41,45
2016-02-11T16:15:06,0
2016-02-11T16:18:52,45
2016-02-11T16:37:33,0
2016-02-11T16:54:42,45
2016-02-11T17:36:04,0
2016-02-11T17:42:47,45
2016-02-11T17:52:45,0
2016-02-11T19:08:28,45
2016-02-11T19:11:30,0
2016-02-12T08:34:22,45
2016-02-12T09:28:21,0
2016-02-12T10:20:57,45
2016-02-12T11:58:37,0
2016-02-12T12:18:38,45
2016-02-12T12:24:15,0
2016-02-12T12:38:06,45
2016-02-12T12:45:53,0
2016-02-12T12:51:38,45
2016-02-12T12:57:07,0
2016-02-12T13:07:16,45
2016-02-12T13:18:56,0
2016-02-12T13:33:09,45
2016-02-12T13:43:10,0
2016-02-12T13:57:39,45
2016-02-12T14:00:50,0
2016-02-12T14:18:21,45
2016-02-12T15:07:00,0
2016-02-12T15:39:19,45
2016-02-12T16:20:17,0
2016-02-12T16:22:36,45
2016-02-12T16:27:33,0
2016-02-12T16:57:42,45
2016-02-12T16:58:06,0
2016-02-12T17:29:56,45
2016-02-12T17:54:01,0
2016-02-12T18:44:13,45
2016-02-12T18:46:01,0
2016-02-12T19:27:59,45
2016-02-12T19:53:16,0
2016-02-12T20:46:55,45
2016-02-12T21:00:25,0
2016-02-13T13:24:42,45
2016-02-13T13:24:57,0
2016-02-13T13:49:53,45
2016-02-13T14:04:32,0
2016-02-13T18:22:28,45
2016-02-13T18:32:45,0
2016-02-14T09:34:27,45
2016-02-14T09:38:52,0
2016-02-14T10:06:52,45
2016-02-14T10:20:40,0
2016-02-14T10:35:09,45
2016-02-14T10:58:46,0
2016-02-14T11:42:16,45
2016-02-14T11:50:48,0
2016-02-14T14:24:25,45
2016-02-14T14:38:15,0
2016-02-14T14:40:55,45
2016-02-14T15:02:41,0
2016-02-14T18:21:32,45
2016-02-14T18:24:52,0
2016-02-15T08:16:55,45
2016-02-15T08:17:22,0
2016-02-15T08:23:19,45
2016-02-15T08:34:46,0
2016-02-15T09:07:46,45
2016-02-15T09:14:13,0
2016-02-15T09:34:38,45
2016-02-15T10:21:20,0
2016-02-15T10:57:59,45
2016-02-15T11:31:38,0
2016-02-15T11:51:25,45
2016-02-15T12:01:35,0
2016-02-15T12:56:01,45
2016-02-15T13:10:46,0
2016-02-15T13:25:17,45
2016-02-15T13:28:31,0
2016-02-15T13:38:09,45
2016-02-15T13:50:18,0
2016-02-15T14:17:02,45
2016-02-15T14:35:12,0
2016-02-15T14:48:09,45
2016-02-15T15:57:55,0
2016-02-15T16:05:03,45
2016-02-15T16:10:24,0
2016-02-15T17:00:25,45
2016-02-15T18:04:25,0
2016-02-15T19:39:38,45
2016-02-15T19:47:58,0
2016-02-16T08:04:21,45
2016-02-16T09:38:29,0
2016-02-16T09:51:16,45
2016-02-16T10:00:50,0
2016-02-16T10:01:45,45
2016-02-16T10:42:41,0
2016-02-16T11:20:32,45
2016-02-16T12:04:37,0
2016-02-16T12:52:06,45
2016-02-16T12:53:36,0
2016-02-16T13:16:23,45
2016-02-16T13:41:30,0
2016-02-16T13:44:26,45
2016-02-16T14:12:40,0
2016-02-16T15:17:13,45
2016-02-16T15:22:02,0
2016-02-16T15:42:14,45
2016-02-16T17:26:36,0
2016-02-16T17:43:36,45
2016-02-16T17:59:49,0
2016-02-16T19:08:50,45
2016-02-16T19:15:03,0
2016-02-16T19:43:16,45
2016-02-16T20:03:29,0
2016-02-17T08:43:12,45
2016-02-17T08:51:30,0
2016-02-17T08:55:06,45
2016-02-17T09:01:42,0
2016-02-17T09:34:49,45
2016-02-17T11:59:08,0
2016-02-17T12:43:06,45
2016-02-17T12:51:11,0
2016-02-17T12:53:49,45
2016-02-17T13:01:39,0
2016-02-17T13:46:06,45
2016-02-17T13:54:56,0
2016-02-17T14:01:57,45
2016-02-17T14:11:14,0
2016-02-17T14:13:17,45
2016-02-17T14:56:40,0
2016-02-17T15:13:45,45
2016-02-17T15:24:46,0
2016-02-17T15:32:02,45
2016-02-17T15:34:08,0
2016-02-17T15:37:09,45
2016-02-17T16:10:32,0
2016-02-17T16:35:28,45
2016-02-17T16:52:11,0
2016-02-17T18:44:44,45
2016-02-17T19:02:13,0
2016-02-17T19:06:07,45
2016-02-17T19:10:50,0
2016-02-18T08:43:10,45
2016-02-18T09:25:37,0
2016-02-18T09:32:08,45
2016-02-18T09:50:38,0
2016-02-18T10:03:30,45
2016-02-18T10:08:57,0
2016-02-18T10:43:06,45
2016-02-18T11:33:56,0
2016-02-18T12:16:47,45
2016-02-18T12:26:16,0
2016-02-18T13:01:22,45
2016-02-18T13:12:20,0
2016-02-18T13:34:42,45
2016-02-18T13:50:47,0
2016-02-18T14:02:58,45
2016-02-18T15:42:50,0
2016-02-18T15:45:23,45
2016-02-18T16:09:18,0
2016-02-19T07:23:44,45
2016-02-19T08:12:36,0
2016-02-19T08:51:14,45
2016-02-19T09:09:20,0
2016-02-19T09:22:02,45
2016-02-19T09:49:13,0
2016-02-19T10:16:45,45
2016-02-19T10:27:22,0
2016-02-19T10:30:25,45
2016-02-19T10:51:36,0
2016-02-19T11:28:08,45
2016-02-19T11:59:16,0
2016-02-19T12:21:32,45
2016-02-19T12:41:49,0
2016-02-19T12:58:43,45
2016-02-19T13:28:26,0
2016-02-19T13:54:48,45
2016-02-19T14:11:20,0
2016-02-19T15:02:26,45
2016-02-19T15:02:27,0
2016-02-19T15:06:20,45
2016-02-19T15:20:34,0
2016-02-19T16:13:43,45
2016-02-19T16:44:57,0
2016-02-19T17:02:12,45
2016-02-19T17:41:50,0
2016-02-19T17:53:13,45
2016-02-19T18:51:31,0
2016-02-19T19:03:50,45
2016-02-19T19:16:51,0
2016-02-19T20:15:26,45
2016-02-19T20:24:57,0
2016-02-20T07:39:14,45
2016-02-20T08:05:16,0
2016-02-20T15:57:56,45
2016-02-20T16:05:09,0
2016-02-21T09:38:17,45
2016-02-21T09:45:10,0
2016-02-21T18:06:01,45
2016-02-21T18:06:12,0
2016-02-22T08:35:03,45
2016-02-22T08:47:09,0
2016-02-22T10:10:42,45
2016-02-22T10:24:10,0
2016-02-22T10:39:08,45
2016-02-22T10:50:36,0
2016-02-22T10:54:40,45
2016-02-22T11:20:05,0
2016-02-22T11:45:19,45
2016-02-22T12:05:29,0
2016-02-22T12:39:17,45
2016-02-22T12:45:07,0
2016-02-22T12:49:20,45
2016-02-22T13:01:17,0
2016-02-22T13:16:01,45
2016-02-22T13:45:02,0
2016-02-22T13:59:27,45
2016-02-22T14:08:46,0
2016-02-22T14:15:53,45
2016-02-22T14:24:15,0
2016-02-22T14:53:16,45
2016-02-22T14:54:28,0
2016-02-22T15:06:20,45
2016-02-22T15:36:40,0
2016-02-22T16:06:31,45
2016-02-22T16:10:31,0
2016-02-22T16:12:54,45
2016-02-22T16:13:11,0
2016-02-22T16:40:37,45
2016-02-22T17:29:18,0
2016-02-22T18:31:52,45
2016-02-22T19:10:37,0
2016-02-22T19:22:42,45
2016-02-22T19:39:15,0
2016-02-23T09:02:18,45
2016-02-23T09:03:48,0
2016-02-23T09:53:57,45
2016-02-23T10:01:44,0
2016-02-23T10:55:01,45
2016-02-23T10:57:36,0
2016-02-23T11:12:28,45
2016-02-23T11:12:58,0
2016-02-23T11:16:44,45
2016-02-23T11:19:55,0
2016-02-23T11:31:08,45
2016-02-23T11:49:30,0
2016-02-23T11:59:33,45
2016-02-23T12:03:18,0
2016-02-23T13:07:35,45
2016-02-23T13:31:55,0
2016-02-23T14:02:23,45
2016-02-23T14:59:17,0
2016-02-23T15:17:30,45
2016-02-23T15:48:31,0
2016-02-23T16:00:11,45
2016-02-23T16:32:30,0
2016-02-23T16:56:34,45
2016-02-23T17:04:26,0
2016-02-23T17:20:36,45
2016-02-23T17:24:08,0
2016-02-23T17:41:50,45
2016-02-23T17:44:40,0
2016-02-23T18:11:41,45
2016-02-23T18:35:52,0
2016-02-24T07:37:50,45
2016-02-24T08:13:42,0
2016-02-24T09:32:46,45
2016-02-24T09:56:51,0
2016-02-24T10:02:08,45
2016-02-24T10:14:52,0
2016-02-24T10:31:36,45
2016-02-24T11:49:04,0
2016-02-24T11:50:17,45
2016-02-24T11:52:49,0
2016-02-24T11:57:06,45
2016-02-24T12:11:52,0
2016-02-24T12:15:58,45
2016-02-24T12:34:15,0
2016-02-24T14:10:58,45
2016-02-24T14:51:47,0
2016-02-24T15:02:14,45
2016-02-24T15:08:10,0
2016-02-24T15:18:24,45
2016-02-24T15:23:18,0
2016-02-24T15:36:12,45
2016-02-24T15:40:50,0
2016-02-24T15:43:27,45
2016-02-24T15:43:49,0
2016-02-24T15:46:20,45
2016-02-24T16:11:22,0
2016-02-24T16:17:35,45
2016-02-24T16:18:11,0
2016-02-24T16:29:16,45
2016-02-24T17:51:56,0
2016-02-24T17:52:07,45
2016-02-24T17:57:44,0
2016-02-24T18:42:29,45
2016-02-24T18:51:11,0
2016-02-25T08:45:39,45
2016-02-25T09:19:51,0
2016-02-25T09:36:50,45
2016-02-25T10:29:38,0
2016-02-25T10:51:18,45
2016-02-25T12:32:19,0
2016-02-25T13:24:50,45
2016-02-25T13:40:24,0
2016-02-25T14:19:15,45
2016-02-25T14:30:25,0
2016-02-25T14:42:33,45
2016-02-25T15:27:11,0
2016-02-25T15:46:20,45
2016-02-25T16:00:53,0
2016-02-25T16:22:51,45
2016-02-25T16:53:22,0
2016-02-25T17:36:22,45
2016-02-25T17:36:43,0
2016-02-26T08:32:31,45
2016-02-26T08:58:21,0
2016-02-26T09:20:00,45
2016-02-26T09:24:09,0
2016-02-26T10:21:07,45
2016-02-26T11:17:53,0
2016-02-26T12:42:12,45
2016-02-26T13:41:35,0
2016-02-26T13:54:25,45
2016-02-26T14:00:15,0
2016-02-26T14:29:09,45
2016-02-26T14:42:55,0
2016-02-26T14:50:06,45
2016-02-26T15:01:09,0
2016-02-26T15:17:18,45
2016-02-26T16:05:30,0
2016-02-26T16:14:45,45
2016-02-26T16:30:10,0
2016-02-26T16:30:54,45
2016-02-26T16:30:55,0
2016-02-26T16:32:22,45
2016-02-26T17:26:05,0
2016-02-26T17:40:48,45
2016-02-26T17:48:07,0
2016-02-26T18:01:22,45
2016-02-26T18:47:28,0
2016-02-26T20:35:06,45
2016-02-26T20:36:26,0
2016-02-27T10:24:09,45
2016-02-27T10:29:10,0
2016-02-27T13:02:03,45
2016-02-27T13:03:16,0
2016-02-27T15:28:08,45
2016-02-27T15:32:03,0
2016-02-28T13:12:58,45
2016-02-28T13:14:16,0
2016-02-28T15:33:51,45
2016-02-28T15:36:14,0
2016-02-29T08:56:19,45
2016-02-29T10:19:31,0
2016-02-29T10:21:23,45
2016-02-29T10:41:03,0
2016-02-29T10:44:23,45
2016-02-29T10:56:36,0
2016-02-29T11:05:34,45
2016-02-29T11:34:12,0
2016-02-29T12:16:58,45
2016-02-29T12:42:26,0
2016-02-29T13:14:25,45
2016-02-29T16:02:52,0
2016-02-29T16:05:48,45
2016-02-29T16:36:37,0
2016-02-29T17:05:21,45
2016-02-29T17:42:12,0
2016-02-29T17:42:35,45
2016-02-29T17:45:02,0
2016-02-29T18:01:54,45
2016-02-29T18:11:41,0
2016-02-29T20:12:33,45
2016-02-29T20:24:13,0
2016-02-29T20:46:29,45
2016-02-29T21:22:19,0
2016-03-01T08:50:20,45
2016-03-01T09:16:33,0
2016-03-01T09:21:52,45
2016-03-01T09:39:23,0
2016-03-01T10:00:23,45
2016-03-01T11:00:19,0
2016-03-01T11:22:12,45
2016-03-01T11:25:41,0
2016-03-01T11:59:17,45
2016-03-01T12:31:17,0
2016-03-01T12:40:07,45
2016-03-01T14:10:17,0
2016-03-01T14:11:15,45
2016-03-01T14:47:24,0
2016-03-01T14:47:53,45
2016-03-01T15:07:41,0
2016-03-01T15:09:42,45
2016-03-01T15:22:33,0
2016-03-01T16:23:50,45
2016-03-01T17:08:18,0
2016-03-01T17:08:53,45
2016-03-01T17:15:55,0
2016-03-01T17:23:51,45
2016-03-01T17:26:56,0
2016-03-01T17:49:02,45
2016-03-01T18:17:31,0
2016-03-02T09:20:43,45
2016-03-02T09:48:38,0
2016-03-02T09:50:31,45
2016-03-02T10:27:50,0
2016-03-02T10:40:42,45
2016-03-02T10:57:31,0
2016-03-02T11:09:55,45
2016-03-02T11:12:47,0
2016-03-02T11:23:59,45
2016-03-02T11:41:21,0
2016-03-02T11:46:28,45
2016-03-02T11:46:53,0
2016-03-02T11:54:13,45
2016-03-02T12:07:04,0
2016-03-02T12:28:45,45
2016-03-02T13:31:11,0
2016-03-02T13:32:28,45
2016-03-02T13:45:34,0
2016-03-02T14:30:19,45
2016-03-02T14:53:42,0
2016-03-02T15:12:13,45
2016-03-02T15:14:17,0
2016-03-02T15:36:08,45
2016-03-02T16:04:32,0
2016-03-02T16:13:31,45
2016-03-02T16:14:53,0
2016-03-02T16:26:25,45
2016-03-02T16:28:25,0
2016-03-02T16:31:48,45
2016-03-02T16:49:29,0
2016-03-02T16:53:55,45
2016-03-02T17:12:16,0
2016-03-02T17:16:10,45
2016-03-02T17:32:41,0
2016-03-02T18:55:31,45
2016-03-02T19:10:38,0
2016-03-02T19:15:28,45
2016-03-02T19:16:28,0
2016-03-03T08:28:53,45
2016-03-03T08:35:02,0
2016-03-03T09:31:27,45
2016-03-03T09:32:52,0
2016-03-03T09:49:42,45
2016-03-03T10:20:40,0
2016-03-03T10:20:48,45
2016-03-03T10:31:19,0
2016-03-03T11:30:51,45
2016-03-03T11:59:40,0
2016-03-03T12:50:16,45
2016-03-03T13:07:42,0
2016-03-03T13:39:23,45
2016-03-03T13:52:36,0
2016-03-03T14:40:29,45
2016-03-03T14:56:34,0
2016-03-03T15:14:44,45
2016-03-03T15:48:50,0
2016-03-03T16:05:54,45
2016-03-03T16:22:32,0
2016-03-03T16:45:30,45
2016-03-03T16:54:26,0
2016-03-03T17:03:29,45
2016-03-03T17:07:33,0
2016-03-03T17:31:07,45
2016-03-03T18:15:04,0
2016-03-03T19:06:26,45
2016-03-03T19:08:36,0
2016-03-03T19:13:54,45
2016-03-03T19:32:47,0
2016-03-04T08:08:44,45
2016-03-04T08:18:30,0
2016-03-04T08:18:35,45
2016-03-04T08:32:08,0
2016-03-04T10:09:00,45
2016-03-04T10:38:28,0
2016-03-04T11:54:32,45
2016-03-04T12:00:19,0
2016-03-04T12:38:34,45
2016-03-04T12:50:26,0
2016-03-04T13:01:51,45
2016-03-04T13:19:25,0
2016-03-04T13:29:44,45
2016-03-04T14:12:47,0
2016-03-04T14:30:58,45
2016-03-04T15:09:06,0
2016-03-04T15:54:02,45
2016-03-04T16:32:29,0
2016-03-04T16:44:37,45
2016-03-04T17:19:13,0
2016-03-04T17:19:58,45
2016-03-04T17:42:59,0
2016-03-05T11:10:39,45
2016-03-05T11:21:11,0
2016-03-05T14:21:32,45
2016-03-05T14:26:55,0
2016-03-05T14:35:09,45
2016-03-05T15:20:04,0
2016-03-05T15:28:14,45
2016-03-05T15:29:07,0
2016-03-06T10:10:04,45
2016-03-06T10:14:45,0
2016-03-06T10:15:09,45
2016-03-06T10:17:01,0
2016-03-06T14:17:11,45
2016-03-06T14:20:59,0
2016-03-06T18:54:08,45
2016-03-06T19:06:29,0
2016-03-07T09:27:44,45
2016-03-07T09:37:28,0
2016-03-07T09:39:48,45
2016-03-07T09:56:12,0
2016-03-07T10:41:38,45
2016-03-07T10:49:00,0
2016-03-07T10:52:29,45
2016-03-07T11:03:54,0
2016-03-07T11:15:14,45
2016-03-07T11:51:04,0
2016-03-07T12:11:29,45
2016-03-07T12:13:11,0
2016-03-07T12:13:28,45
2016-03-07T12:30:58,0
2016-03-07T13:31:11,45
2016-03-07T14:41:09,0
2016-03-07T15:57:41,45
2016-03-07T16:37:41,0
2016-03-07T17:04:03,45
2016-03-07T17:10:20,0
2016-03-07T17:30:55,45
2016-03-07T17:37:55,0
2016-03-07T18:43:50,45
2016-03-07T19:07:58,0
2016-03-08T08:06:52,45
2016-03-08T08:10:23,0
2016-03-08T08:23:56,45
2016-03-08T08:25:52,0
2016-03-08T08:58:49,45
2016-03-08T09:08:50,0
2016-03-08T09:11:04,45
2016-03-08T09:16:18,0
2016-03-08T09:17:40,45
2016-03-08T09:37:04,0
2016-03-08T10:16:11,45
2016-03-08T11:09:40,0
2016-03-08T11:59:02,45
2016-03-08T11:59:11,0
2016-03-08T12:01:38,45
2016-03-08T12:10:07,0
2016-03-08T13:15:34,45
2016-03-08T13:30:25,0
2016-03-08T14:00:52,45
2016-03-08T14:10:25,0
2016-03-08T14:52:32,45
2016-03-08T15:13:25,0
2016-03-08T15:37:55,45
2016-03-08T17:15:04,0
2016-03-08T17:50:13,45
2016-03-08T18:08:50,0
2016-03-08T19:36:00,45
2016-03-08T19:48:32,0
2016-03-09T07:44:51,45
2016-03-09T08:05:42,0
2016-03-09T08:54:10,45
2016-03-09T09:21:06,0
2016-03-09T09:44:08,45
2016-03-09T09:57:15,0
2016-03-09T10:03:29,45
2016-03-09T11:34:47,0
2016-03-09T12:13:53,45
2016-03-09T12:14:57,0
2016-03-09T12:35:35,45
2016-03-09T12:49:24,0
2016-03-09T13:11:46,45
2016-03-09T14:03:16,0
2016-03-09T14:19:36,45
2016-03-09T14:48:41,0
2016-03-09T15:04:17,45
2016-03-09T15:05:32,0
2016-03-09T15:23:32,45
2016-03-09T15:29:30,0
2016-03-09T15:30:57,45
2016-03-09T15:57:30,0
2016-03-09T15:57:59,45
2016-03-09T15:59:22,0
2016-03-09T16:17:50,45
2016-03-09T16:33:30,0
2016-03-09T16:34:24,45
2016-03-09T16:49:37,0
2016-03-09T16:50:41,45
2016-03-09T17:02:24,0
2016-03-10T06:34:07,45
2016-03-10T06:36:24,0
2016-03-10T07:38:35,45
2016-03-10T08:05:11,0
2016-03-10T08:18:48,45
2016-03-10T08:42:40,0
2016-03-10T09:28:46,45
2016-03-10T09:35:46,0
2016-03-10T09:48:39,45
2016-03-10T10:54:02,0
2016-03-10T10:54:15,45
2016-03-10T11:46:45,0
2016-03-10T11:55:43,45
2016-03-10T12:05:18,0
2016-03-10T13:17:34,45
2016-03-10T13:25:03,0
2016-03-10T13:29:24,45
2016-03-10T13:36:34,0
2016-03-10T13:54:31,45
2016-03-10T14:03:24,0
2016-03-10T14:17:07,45
2016-03-10T15:13:12,0
2016-03-10T15:31:27,45
2016-03-10T15:33:19,0
2016-03-10T16:22:52,45
2016-03-10T17:00:11,0
2016-03-10T19:02:23,45
2016-03-10T19:11:33,0
2016-03-10T19:15:09,45
2016-03-10T19:34:52,0
2016-03-10T20:03:32,45
2016-03-10T20:06:04,0
2016-03-11T07:10:10,45
2016-03-11T07:45:50,0
2016-03-11T07:57:56,45
2016-03-11T07:59:29,0
2016-03-11T09:26:54,45
2016-03-11T11:05:04,0
2016-03-11T11:27:05,45
2016-03-11T11:31:25,0
2016-03-11T12:07:25,45
2016-03-11T12:15:46,0
2016-03-11T12:47:16,45
2016-03-11T12:53:01,0
2016-03-11T13:28:53,45
2016-03-11T13:30:23,0
2016-03-11T14:09:25,45
2016-03-11T14:15:33,0
2016-03-11T14:53:58,45
2016-03-11T14:54:13,0
2016-03-11T15:12:41,45
2016-03-11T15:46:47,0
2016-03-11T16:09:33,45
2016-03-11T16:13:02,0
2016-03-11T16:25:27,45
2016-03-11T16:25:46,0
2016-03-11T16:49:20,45
2016-03-11T17:45:05,0
2016-03-11T18:07:03,45
2016-03-11T18:44:48,0
2016-03-12T17:05:47,45
2016-03-12T17:17:21,0
2016-03-13T11:09:16,45
2016-03-13T11:22:39,0
2016-03-13T17:26:46,45
2016-03-13T17:52:39,0
2016-03-14T08:28:59,45
2016-03-14T09:12:24,0
2016-03-14T09:58:14,45
2016-03-14T10:12:40,0
2016-03-14T10:58:24,45
2016-03-14T11:17:17,0
2016-03-14T11:26:17,45
2016-03-14T11:58:25,0
2016-03-14T12:40:42,45
2016-03-14T12:49:28,0
2016-03-14T13:13:05,45
2016-03-14T13:20:10,0
2016-03-14T13:52:10,45
2016-03-14T14:28:14,0
2016-03-14T14:37:14,45
2016-03-14T14:56:52,0
2016-03-14T15:47:07,45
2016-03-14T15:59:48,0
2016-03-14T16:35:37,45
2016-03-14T16:39:41,0
2016-03-14T16:43:24,45
2016-03-14T16:45:30,0
2016-03-14T16:50:36,45
2016-03-14T16:51:31,0
2016-03-14T16:52:31,45
2016-03-14T17:04:37,0
2016-03-14T18:16:39,45
2016-03-14T18:26:54,0
2016-03-14T18:35:19,45
2016-03-14T18:38:20,0


================================================
FILE: examples/data/lightbulb-02.csv
================================================
time,watts
2016-01-01T06:31:41,0
2016-01-01T08:47:33,45
2016-01-01T08:55:18,0
2016-01-01T10:00:48,45
2016-01-01T10:08:50,0
2016-01-01T10:10:24,45
2016-01-01T11:23:20,0
2016-01-01T11:42:31,45
2016-01-01T11:45:20,0
2016-01-01T12:50:15,45
2016-01-01T13:18:18,0
2016-01-01T13:50:07,45
2016-01-01T14:11:31,0
2016-01-01T14:25:53,45
2016-01-01T14:39:33,0
2016-01-01T15:37:46,45
2016-01-01T16:10:38,0
2016-01-01T16:32:16,45
2016-01-01T17:13:26,0
2016-01-01T17:39:31,45
2016-01-01T17:39:47,0
2016-01-01T17:45:48,45
2016-01-01T17:48:05,0
2016-01-01T17:51:56,45
2016-01-01T18:05:24,0
2016-01-02T15:45:46,45
2016-01-02T15:45:55,0
2016-01-03T14:33:26,45
2016-01-03T14:38:14,0
2016-01-03T16:31:22,45
2016-01-03T16:49:04,0
2016-01-04T10:42:31,45
2016-01-04T11:09:37,0
2016-01-04T11:20:13,45
2016-01-04T11:21:33,0
2016-01-04T11:27:47,45
2016-01-04T11:36:16,0
2016-01-04T12:39:55,45
2016-01-04T13:00:29,0
2016-01-04T13:03:53,45
2016-01-04T13:09:55,0
2016-01-04T13:10:20,45
2016-01-04T13:10:37,0
2016-01-04T13:18:34,45
2016-01-04T13:38:37,0
2016-01-04T14:08:21,45
2016-01-04T14:42:27,0
2016-01-04T15:07:52,45
2016-01-04T15:52:14,0
2016-01-04T16:04:29,45
2016-01-04T16:15:25,0
2016-01-05T08:02:02,45
2016-01-05T08:03:35,0
2016-01-05T08:56:21,45
2016-01-05T09:02:10,0
2016-01-05T09:05:53,45
2016-01-05T10:05:30,0
2016-01-05T10:08:57,45
2016-01-05T12:18:55,0
2016-01-05T13:07:24,45
2016-01-05T13:55:42,0
2016-01-05T13:59:56,45
2016-01-05T15:19:40,0
2016-01-05T15:19:42,45
2016-01-05T15:27:35,0
2016-01-05T15:33:54,45
2016-01-05T16:14:10,0
2016-01-05T16:55:36,45
2016-01-05T17:49:23,0
2016-01-05T18:17:18,45
2016-01-05T18:31:12,0
2016-01-05T19:31:30,45
2016-01-05T19:36:20,0
2016-01-06T08:57:31,45
2016-01-06T09:02:53,0
2016-01-06T10:00:16,45
2016-01-06T10:06:05,0
2016-01-06T10:17:46,45
2016-01-06T10:29:43,0
2016-01-06T10:34:37,45
2016-01-06T10:41:55,0
2016-01-06T10:52:34,45
2016-01-06T10:57:40,0
2016-01-06T11:11:26,45
2016-01-06T11:16:26,0
2016-01-06T11:34:55,45
2016-01-06T11:51:34,0
2016-01-06T12:47:23,45
2016-01-06T12:56:30,0
2016-01-06T13:13:51,45
2016-01-06T13:30:22,0
2016-01-06T14:11:07,45
2016-01-06T14:46:05,0
2016-01-06T14:49:56,45
2016-01-06T14:51:46,0
2016-01-06T14:57:43,45
2016-01-06T15:28:08,0
2016-01-06T15:28:48,45
2016-01-06T16:47:16,0
2016-01-06T17:19:57,45
2016-01-06T17:33:52,0
2016-01-06T17:44:32,45
2016-01-06T17:44:43,0
2016-01-06T17:58:08,45
2016-01-06T18:07:55,0
2016-01-06T18:22:21,45
2016-01-06T18:39:46,0
2016-01-06T20:23:49,45
2016-01-06T20:27:51,0
2016-01-07T09:22:47,45
2016-01-07T09:48:34,0
2016-01-07T10:06:48,45
2016-01-07T10:07:22,0
2016-01-07T10:09:37,45
2016-01-07T10:23:26,0
2016-01-07T10:27:16,45
2016-01-07T10:37:47,0
2016-01-07T11:44:21,45
2016-01-07T11:52:01,0
2016-01-07T12:53:30,45
2016-01-07T13:14:18,0
2016-01-07T13:20:07,45
2016-01-07T14:58:06,0
2016-01-07T15:16:11,45
2016-01-07T15:19:23,0
2016-01-07T15:45:40,45
2016-01-07T15:45:58,0
2016-01-07T16:30:08,45
2016-01-07T17:03:31,0
2016-01-07T17:38:42,45
2016-01-07T18:20:57,0
2016-01-08T08:20:15,45
2016-01-08T08:27:06,0
2016-01-08T08:46:19,45
2016-01-08T08:56:04,0
2016-01-08T09:28:55,45
2016-01-08T11:04:50,0
2016-01-08T11:14:24,45
2016-01-08T12:12:13,0
2016-01-08T12:53:39,45
2016-01-08T14:09:10,0
2016-01-08T15:14:59,45
2016-01-08T15:43:11,0
2016-01-08T16:14:05,45
2016-01-08T16:18:03,0
2016-01-08T17:02:24,45
2016-01-08T17:02:41,0
2016-01-08T17:40:22,45
2016-01-08T17:42:16,0
2016-01-09T10:42:03,45
2016-01-09T10:53:59,0
2016-01-09T15:06:01,45
2016-01-09T17:10:29,0
2016-01-10T17:55:03,45
2016-01-10T18:12:09,0
2016-01-11T08:33:00,45
2016-01-11T09:48:13,0
2016-01-11T10:00:12,45
2016-01-11T10:47:44,0
2016-01-11T13:50:34,45
2016-01-11T13:54:30,0
2016-01-11T14:01:29,45
2016-01-11T14:17:43,0
2016-01-11T14:20:39,45
2016-01-11T14:24:53,0
2016-01-11T14:28:50,45
2016-01-11T14:35:30,0
2016-01-11T15:22:55,45
2016-01-11T16:13:10,0
2016-01-11T16:44:06,45
2016-01-11T17:10:15,0
2016-01-11T17:23:17,45
2016-01-11T17:40:20,0
2016-01-11T18:10:48,45
2016-01-11T18:35:20,0
2016-01-11T18:50:27,45
2016-01-11T18:59:32,0
2016-01-12T07:34:44,45
2016-01-12T07:36:45,0
2016-01-12T09:36:31,45
2016-01-12T09:44:03,0
2016-01-12T10:03:30,45
2016-01-12T10:43:22,0
2016-01-12T11:05:40,45
2016-01-12T11:39:23,0
2016-01-12T11:56:04,45
2016-01-12T12:11:51,0
2016-01-12T12:40:06,45
2016-01-12T12:48:57,0
2016-01-12T13:10:14,45
2016-01-12T13:10:40,0
2016-01-12T13:16:46,45
2016-01-12T13:24:33,0
2016-01-12T14:36:22,45
2016-01-12T15:34:14,0
2016-01-12T16:32:21,45
2016-01-12T17:28:36,0
2016-01-12T17:41:38,45
2016-01-12T17:46:25,0
2016-01-12T18:37:43,45
2016-01-12T18:38:53,0
2016-01-12T18:55:09,45
2016-01-12T19:31:58,0
2016-01-13T08:50:30,45
2016-01-13T08:55:11,0
2016-01-13T09:28:18,45
2016-01-13T10:54:06,0
2016-01-13T11:06:06,45
2016-01-13T11:45:56,0
2016-01-13T11:55:24,45
2016-01-13T12:24:51,0
2016-01-13T12:27:56,45
2016-01-13T12:40:24,0
2016-01-13T13:05:42,45
2016-01-13T13:38:45,0
2016-01-13T14:37:30,45
2016-01-13T16:30:32,0
2016-01-13T17:59:38,45
2016-01-13T18:13:06,0
2016-01-14T09:25:46,45
2016-01-14T09:30:07,0
2016-01-14T09:50:01,45
2016-01-14T10:21:38,0
2016-01-14T10:33:37,45
2016-01-14T10:53:28,0
2016-01-14T11:27:36,45
2016-01-14T11:28:15,0
2016-01-14T11:33:27,45
2016-01-14T12:19:33,0
2016-01-14T12:57:03,45
2016-01-14T13:09:45,0
2016-01-14T13:09:52,45
2016-01-14T13:15:03,0
2016-01-14T13:32:48,45
2016-01-14T16:22:06,0
2016-01-14T16:26:37,45
2016-01-14T16:28:49,0
2016-01-14T16:38:45,45
2016-01-14T16:59:18,0
2016-01-14T17:02:28,45
2016-01-14T17:27:39,0
2016-01-14T17:34:13,45
2016-01-14T17:53:06,0
2016-01-14T17:58:58,45
2016-01-14T18:15:37,0
2016-01-14T20:00:27,45
2016-01-14T20:26:56,0
2016-01-15T08:42:52,45
2016-01-15T08:43:48,0
2016-01-15T09:22:29,45
2016-01-15T09:32:07,0
2016-01-15T10:01:51,45
2016-01-15T10:02:10,0
2016-01-15T10:11:19,45
2016-01-15T10:48:49,0
2016-01-15T10:49:41,45
2016-01-15T11:29:26,0
2016-01-15T12:32:33,45
2016-01-15T12:36:13,0
2016-01-15T12:59:30,45
2016-01-15T13:15:44,0
2016-01-15T13:20:49,45
2016-01-15T13:31:35,0
2016-01-15T13:40:33,45
2016-01-15T14:18:13,0
2016-01-15T14:24:15,45
2016-01-15T14:54:38,0
2016-01-15T15:11:01,45
2016-01-15T15:20:14,0
2016-01-15T16:36:52,45
2016-01-15T16:41:11,0
2016-01-15T17:13:50,45
2016-01-15T17:20:14,0
2016-01-15T18:05:23,45
2016-01-15T18:13:49,0
2016-01-16T07:20:36,45
2016-01-16T07:28:16,0
2016-01-16T13:01:59,45
2016-01-16T13:06:51,0
2016-01-17T08:14:17,45
2016-01-17T08:30:32,0
2016-01-18T08:06:16,45
2016-01-18T08:22:41,0
2016-01-18T08:43:45,45
2016-01-18T08:44:54,0
2016-01-18T09:42:43,45
2016-01-18T11:05:15,0
2016-01-18T11:10:04,45
2016-01-18T11:12:37,0
2016-01-18T12:40:38,45
2016-01-18T13:03:28,0
2016-01-18T13:18:22,45
2016-01-18T13:23:39,0
2016-01-18T13:45:24,45
2016-01-18T13:56:36,0
2016-01-18T14:00:21,45
2016-01-18T14:05:44,0
2016-01-18T14:23:40,45
2016-01-18T14:26:02,0
2016-01-18T14:37:55,45
2016-01-18T14:58:37,0
2016-01-18T15:04:04,45
2016-01-18T16:41:15,0
2016-01-18T17:04:35,45
2016-01-18T17:33:47,0
2016-01-18T17:50:17,45
2016-01-18T19:06:18,0
2016-01-19T08:06:27,45
2016-01-19T08:30:40,0
2016-01-19T08:46:11,45
2016-01-19T08:50:32,0
2016-01-19T08:52:31,45
2016-01-19T08:54:46,0
2016-01-19T09:00:46,45
2016-01-19T09:06:35,0
2016-01-19T09:09:08,45
2016-01-19T09:44:53,0
2016-01-19T10:20:10,45
2016-01-19T10:28:14,0
2016-01-19T10:46:20,45
2016-01-19T10:55:14,0
2016-01-19T11:04:08,45
2016-01-19T11:12:40,0
2016-01-19T11:18:46,45
2016-01-19T11:28:24,0
2016-01-19T11:30:58,45
2016-01-19T12:06:06,0
2016-01-19T12:22:51,45
2016-01-19T12:25:38,0
2016-01-19T12:58:48,45
2016-01-19T14:30:30,0
2016-01-19T14:35:13,45
2016-01-19T14:45:01,0
2016-01-19T14:48:15,45
2016-01-19T14:56:46,0
2016-01-19T15:18:07,45
2016-01-19T15:22:33,0
2016-01-19T15:32:16,45
2016-01-19T15:46:25,0
2016-01-19T15:47:02,45
2016-01-19T17:09:14,0
2016-01-19T17:10:06,45
2016-01-19T17:34:19,0
2016-01-19T18:08:22,45
2016-01-19T18:08:56,0
2016-01-20T08:32:20,45
2016-01-20T08:42:04,0
2016-01-20T08:52:07,45
2016-01-20T08:55:17,0
2016-01-20T09:13:34,45
2016-01-20T09:15:52,0
2016-01-20T09:20:03,45
2016-01-20T09:29:18,0
2016-01-20T09:52:55,45
2016-01-20T10:07:45,0
2016-01-20T10:19:17,45
2016-01-20T10:26:08,0
2016-01-20T11:05:20,45
2016-01-20T11:43:15,0
2016-01-20T11:44:08,45
2016-01-20T11:48:44,0
2016-01-20T12:03:47,45
2016-01-20T12:05:28,0
2016-01-20T12:17:26,45
2016-01-20T12:26:11,0
2016-01-20T13:25:34,45
2016-01-20T14:39:33,0
2016-01-20T14:44:22,45
2016-01-20T15:05:29,0
2016-01-20T15:07:03,45
2016-01-20T15:52:30,0
2016-01-20T16:16:53,45
2016-01-20T16:42:53,0
2016-01-20T16:55:40,45
2016-01-20T17:09:03,0
2016-01-20T17:19:13,45
2016-01-20T17:38:26,0
2016-01-20T18:02:13,45
2016-01-20T18:04:41,0
2016-01-20T19:09:34,45
2016-01-20T19:13:30,0
2016-01-20T20:18:15,45
2016-01-20T20:36:33,0
2016-01-20T21:24:20,45
2016-01-20T22:02:01,0
2016-01-21T08:01:41,45
2016-01-21T08:02:03,0
2016-01-21T08:58:20,45
2016-01-21T09:05:01,0
2016-01-21T09:40:36,45
2016-01-21T09:50:18,0
2016-01-21T09:52:32,45
2016-01-21T10:48:35,0
2016-01-21T11:31:49,45
2016-01-21T11:34:37,0
2016-01-21T11:35:10,45
2016-01-21T11:49:24,0
2016-01-21T11:59:06,45
2016-01-21T12:03:49,0
2016-01-21T12:59:31,45
2016-01-21T13:00:16,0
2016-01-21T13:17:05,45
2016-01-21T14:00:45,0
2016-01-21T14:14:07,45
2016-01-21T14:59:21,0
2016-01-21T15:02:22,45
2016-01-21T15:06:29,0
2016-01-21T15:52:27,45
2016-01-21T15:53:57,0
2016-01-21T16:07:47,45
2016-01-21T16:11:19,0
2016-01-21T16:25:46,45
2016-01-21T16:55:31,0
2016-01-21T17:02:21,45
2016-01-21T17:05:54,0
2016-01-21T17:19:01,45
2016-01-21T17:26:05,0
2016-01-21T17:34:14,45
2016-01-21T17:34:21,0
2016-01-21T17:39:26,45
2016-01-21T18:12:19,0
2016-01-21T18:42:14,45
2016-01-21T18:43:20,0
2016-01-21T19:06:24,45
2016-01-21T19:16:36,0
2016-01-21T19:51:25,45
2016-01-21T20:27:38,0
2016-01-22T09:40:46,45
2016-01-22T10:02:36,0
2016-01-22T10:10:08,45
2016-01-22T10:32:20,0
2016-01-22T10:37:20,45
2016-01-22T11:04:54,0
2016-01-22T11:12:05,45
2016-01-22T12:03:59,0
2016-01-22T13:10:16,45
2016-01-22T13:25:54,0
2016-01-22T13:37:29,45
2016-01-22T14:24:09,0
2016-01-22T14:26:29,45
2016-01-22T14:52:02,0
2016-01-22T15:43:32,45
2016-01-22T15:57:01,0
2016-01-22T16:34:20,45
2016-01-22T16:35:29,0
2016-01-23T09:48:18,45
2016-01-23T09:58:01,0
2016-01-23T13:09:24,45
2016-01-23T13:21:23,0
2016-01-24T10:19:03,45
2016-01-24T10:21:54,0
2016-01-25T09:01:32,45
2016-01-25T09:24:10,0
2016-01-25T09:31:04,45
2016-01-25T09:37:24,0
2016-01-25T09:38:31,45
2016-01-25T10:29:03,0
2016-01-25T10:40:56,45
2016-01-25T11:18:50,0
2016-01-25T12:24:08,45
2016-01-25T12:30:18,0
2016-01-25T13:05:17,45
2016-01-25T13:31:29,0
2016-01-25T14:12:43,45
2016-01-25T14:37:54,0
2016-01-25T14:47:27,45
2016-01-25T14:51:11,0
2016-01-25T14:59:57,45
2016-01-25T15:00:55,0
2016-01-25T15:29:44,45
2016-01-25T15:44:13,0
2016-01-25T16:34:50,45
2016-01-25T16:38:35,0
2016-01-25T16:43:16,45
2016-01-25T16:58:45,0
2016-01-25T16:59:06,45
2016-01-25T17:13:39,0
2016-01-25T17:21:09,45
2016-01-25T17:45:34,0
2016-01-25T18:37:03,45
2016-01-25T18:50:24,0
2016-01-26T07:17:23,45
2016-01-26T07:19:26,0
2016-01-26T07:52:18,45
2016-01-26T09:16:34,0
2016-01-26T09:17:52,45
2016-01-26T10:11:10,0
2016-01-26T10:19:21,45
2016-01-26T11:40:35,0
2016-01-26T11:42:49,45
2016-01-26T11:43:27,0
2016-01-26T12:06:09,45
2016-01-26T12:18:42,0
2016-01-26T12:20:40,45
2016-01-26T12:24:29,0
2016-01-26T13:42:21,45
2016-01-26T13:54:22,0
2016-01-26T14:18:56,45
2016-01-26T14:33:57,0
2016-01-26T14:36:41,45
2016-01-26T14:36:43,0
2016-01-26T14:40:02,45
2016-01-26T14:44:17,0
2016-01-26T15:25:46,45
2016-01-26T15:47:04,0
2016-01-26T16:11:01,45
2016-01-26T16:12:48,0
2016-01-26T16:44:29,45
2016-01-26T16:56:12,0
2016-01-26T17:14:29,45
2016-01-26T17:38:50,0
2016-01-26T18:12:16,45
2016-01-26T18:15:00,0
2016-01-26T20:55:25,45
2016-01-26T21:09:32,0
2016-01-27T07:29:08,45
2016-01-27T07:47:49,0
2016-01-27T08:17:20,45
2016-01-27T08:24:27,0
2016-01-27T08:36:15,45
2016-01-27T09:10:25,0
2016-01-27T10:23:27,45
2016-01-27T11:39:46,0
2016-01-27T13:06:50,45
2016-01-27T13:38:45,0
2016-01-27T13:42:51,45
2016-01-27T14:00:53,0
2016-01-27T14:32:08,45
2016-01-27T15:09:45,0
2016-01-27T15:15:38,45
2016-01-27T15:50:18,0
2016-01-27T16:08:47,45
2016-01-27T16:09:01,0
2016-01-27T16:21:50,45
2016-01-27T16:29:35,0
2016-01-27T16:46:55,45
2016-01-27T16:50:45,0
2016-01-27T17:03:48,45
2016-01-27T17:16:06,0
2016-01-27T18:03:05,45
2016-01-27T19:14:46,0
2016-01-27T19:17:44,45
2016-01-27T19:19:52,0
2016-01-28T08:28:04,45
2016-01-28T08:47:59,0
2016-01-28T09:19:05,45
2016-01-28T09:59:40,0
2016-01-28T10:16:29,45
2016-01-28T10:17:19,0
2016-01-28T11:13:23,45
2016-01-28T11:33:32,0
2016-01-28T12:13:47,45
2016-01-28T12:33:29,0
2016-01-28T13:11:43,45
2016-01-28T13:32:34,0
2016-01-28T13:33:24,45
2016-01-28T13:37:43,0
2016-01-28T13:40:34,45
2016-01-28T14:04:18,0
2016-01-28T14:10:33,45
2016-01-28T14:14:14,0
2016-01-28T14:33:07,45
2016-01-28T15:00:32,0
2016-01-28T15:33:14,45
2016-01-28T17:10:10,0
2016-01-28T17:52:43,45
2016-01-28T18:10:57,0
2016-01-28T19:02:09,45
2016-01-28T19:08:26,0
2016-01-28T19:33:54,45
2016-01-28T19:37:33,0
2016-01-28T23:26:33,45
2016-01-28T23:34:17,0
2016-01-29T09:10:22,45
2016-01-29T09:21:39,0
2016-01-29T09:22:35,45
2016-01-29T10:18:46,0
2016-01-29T10:40:48,45
2016-01-29T10:44:05,0
2016-01-29T11:00:05,45
2016-01-29T11:06:05,0
2016-01-29T11:19:02,45
2016-01-29T11:27:11,0
2016-01-29T11:48:56,45
2016-01-29T12:01:12,0
2016-01-29T13:22:54,45
2016-01-29T13:40:31,0
2016-01-29T13:44:21,45
2016-01-29T13:47:43,0
2016-01-29T14:08:39,45
2016-01-29T14:41:34,0
2016-01-29T14:58:07,45
2016-01-29T15:12:28,0
2016-01-29T15:28:49,45
2016-01-29T15:32:38,0
2016-01-29T15:39:24,45
2016-01-29T15:49:18,0
2016-01-29T16:13:52,45
2016-01-29T16:24:58,0
2016-01-29T16:30:30,45
2016-01-29T16:35:53,0
2016-01-29T16:40:27,45
2016-01-29T16:51:08,0
2016-01-29T17:09:35,45
2016-01-29T17:50:39,0
2016-01-29T17:59:12,45
2016-01-29T18:14:58,0
2016-01-29T18:36:58,45
2016-01-29T18:38:43,0
2016-01-29T18:56:46,45
2016-01-29T19:03:32,0
2016-01-30T11:10:48,45
2016-01-30T11:14:38,0
2016-01-30T19:16:16,45
2016-01-30T19:23:40,0
2016-01-31T15:36:43,45
2016-01-31T15:50:52,0
2016-02-01T08:03:57,45
2016-02-01T08:14:37,0
2016-02-01T08:30:19,45
2016-02-01T08:37:35,0
2016-02-01T08:40:38,45
2016-02-01T09:38:59,0
2016-02-01T09:42:15,45
2016-02-01T10:34:51,0
2016-02-01T10:38:37,45
2016-02-01T10:39:45,0
2016-02-01T11:40:15,45
2016-02-01T12:05:37,0
2016-02-01T13:10:28,45
2016-02-01T13:10:36,0
2016-02-01T13:37:29,45
2016-02-01T14:08:01,0
2016-02-01T14:25:42,45
2016-02-01T14:46:34,0
2016-02-01T14:54:02,45
2016-02-01T15:19:06,0
2016-02-01T15:33:53,45
2016-02-01T15:59:30,0
2016-02-01T16:08:06,45
2016-02-01T16:37:44,0
2016-02-01T16:57:55,45
2016-02-01T17:01:13,0
2016-02-01T17:22:49,45
2016-02-01T18:16:30,0
2016-02-01T18:38:30,45
2016-02-01T18:39:42,0
2016-02-02T08:50:14,45
2016-02-02T09:03:19,0
2016-02-02T09:11:14,45
2016-02-02T09:33:48,0
2016-02-02T09:49:37,45
2016-02-02T09:51:15,0
2016-02-02T10:21:07,45
2016-02-02T10:26:21,0
2016-02-02T10:57:13,45
2016-02-02T11:11:21,0
2016-02-02T11:44:55,45
2016-02-02T11:48:10,0
2016-02-02T11:48:36,45
2016-02-02T12:05:01,0
2016-02-02T13:01:29,45
2016-02-02T13:04:52,0
2016-02-02T13:34:44,45
2016-02-02T13:59:52,0
2016-02-02T14:10:55,45
2016-02-02T14:26:17,0
2016-02-02T14:32:39,45
2016-02-02T14:47:24,0
2016-02-02T15:31:51,45
2016-02-02T15:34:55,0
2016-02-02T16:11:39,45
2016-02-02T16:20:26,0
2016-02-02T17:03:16,45
2016-02-02T17:18:44,0
2016-02-02T17:38:04,45
2016-02-02T17:50:31,0
2016-02-02T18:33:12,45
2016-02-02T18:40:15,0
2016-02-02T19:03:09,45
2016-02-02T19:27:16,0
2016-02-02T20:15:08,45
2016-02-02T20:19:42,0
2016-02-03T09:20:02,45
2016-02-03T09:27:58,0
2016-02-03T09:32:22,45
2016-02-03T09:43:36,0
2016-02-03T09:44:50,45
2016-02-03T10:08:53,0
2016-02-03T10:52:25,45
2016-02-03T11:19:31,0
2016-02-03T12:16:42,45
2016-02-03T12:25:32,0
2016-02-03T13:12:47,45
2016-02-03T13:34:41,0
2016-02-03T13:36:06,45
2016-02-03T13:42:54,0
2016-02-03T13:43:32,45
2016-02-03T14:48:17,0
2016-02-03T14:54:08,45
2016-02-03T15:00:00,0
2016-02-03T15:25:24,45
2016-02-03T17:38:28,0
2016-02-03T18:07:05,45
2016-02-03T18:26:50,0
2016-02-03T18:26:58,45
2016-02-03T18:32:38,0
2016-02-04T08:35:04,45
2016-02-04T08:44:39,0
2016-02-04T09:19:55,45
2016-02-04T09:24:41,0
2016-02-04T09:42:48,45
2016-02-04T09:47:42,0
2016-02-04T10:13:12,45
2016-02-04T10:15:35,0
2016-02-04T10:22:12,45
2016-02-04T10:22:48,0
2016-02-04T10:30:19,45
2016-02-04T10:57:32,0
2016-02-04T10:58:57,45
2016-02-04T11:09:32,0
2016-02-04T11:12:38,45
2016-02-04T11:17:45,0
2016-02-04T11:22:03,45
2016-02-04T11:30:22,0
2016-02-04T12:03:48,45
2016-02-04T12:19:42,0
2016-02-04T12:49:09,45
2016-02-04T13:14:09,0
2016-02-04T13:37:27,45
2016-02-04T13:37:39,0
2016-02-04T13:54:03,45
2016-02-04T15:48:36,0
2016-02-04T15:50:01,45
2016-02-04T16:11:11,0
2016-02-04T16:28:38,45
2016-02-04T16:38:41,0
2016-02-04T17:22:34,45
2016-02-04T17:33:56,0
2016-02-04T17:36:34,45
2016-02-04T18:38:53,0
2016-02-04T19:55:18,45
2016-02-04T20:05:52,0
2016-02-05T08:35:58,45
2016-02-05T08:37:49,0
2016-02-05T09:06:11,45
2016-02-05T10:03:00,0
2016-02-05T10:05:48,45
2016-02-05T10:43:32,0
2016-02-05T10:56:48,45
2016-02-05T10:58:48,0
2016-02-05T11:16:47,45
2016-02-05T12:16:48,0
2016-02-05T13:12:23,45
2016-02-05T13:15:14,0
2016-02-05T13:45:20,45
2016-02-05T14:37:20,0
2016-02-05T14:52:07,45
2016-02-05T15:36:08,0
2016-02-05T15:44:18,45
2016-02-05T15:45:53,0
2016-02-05T15:50:10,45
2016-02-05T15:59:14,0
2016-02-05T16:12:00,45
2016-02-05T16:23:30,0
2016-02-05T16:26:15,45
2016-02-05T16:32:02,0
2016-02-05T16:46:26,45
2016-02-05T16:54:01,0
2016-02-06T12:57:24,45
2016-02-06T13:55:21,0
2016-02-06T16:47:35,45
2016-02-06T16:48:37,0
2016-02-08T09:05:54,45
2016-02-08T09:54:47,0
2016-02-08T10:21:50,45
2016-02-08T10:28:47,0
2016-02-08T10:34:54,45
2016-02-08T10:41:06,0
2016-02-08T11:15:30,45
2016-02-08T11:31:10,0
2016-02-08T11:45:16,45
2016-02-08T12:11:20,0
2016-02-08T12:43:34,45
2016-02-08T13:00:50,0
2016-02-08T13:05:50,45
2016-02-08T13:37:51,0
2016-02-08T13:41:56,45
2016-02-08T13:52:59,0
2016-02-08T14:11:41,45
2016-02-08T17:04:26,0
2016-02-08T17:13:31,45
2016-02-08T17:16:06,0
2016-02-08T17:21:40,45
2016-02-08T17:38:30,0
2016-02-08T17:45:56,45
2016-02-08T17:52:31,0
2016-02-08T18:56:44,45
2016-02-08T18:58:58,0
2016-02-08T20:05:03,45
2016-02-08T20:13:40,0
2016-02-09T08:46:22,45
2016-02-09T09:02:55,0
2016-02-09T09:35:18,45
2016-02-09T09:43:02,0
2016-02-09T09:49:41,45
2016-02-09T09:52:40,0
2016-02-09T09:57:46,45
2016-02-09T10:01:03,0
2016-02-09T10:10:34,45
2016-02-09T10:23:33,0
2016-02-09T10:27:06,45
2016-02-09T11:25:05,0
2016-02-09T11:44:38,45
2016-02-09T11:44:53,0
2016-02-09T13:06:17,45
2016-02-09T13:29:40,0
2016-02-09T13:29:46,45
2016-02-09T13:39:27,0
2016-02-09T13:42:50,45
2016-02-09T13:48:48,0
2016-02-09T14:24:43,45
2016-02-09T14:44:47,0
2016-02-09T15:13:29,45
2016-02-09T15:14:54,0
2016-02-09T15:24:56,45
2016-02-09T15:54:54,0
2016-02-09T16:10:14,45
2016-02-09T16:15:20,0
2016-02-09T16:20:04,45
2016-02-09T16:35:46,0
2016-02-09T17:13:36,45
2016-02-09T17:16:37,0
2016-02-09T17:27:19,45
2016-02-09T17:31:29,0
2016-02-09T17:42:49,45
2016-02-09T17:43:42,0
2016-02-09T17:49:02,45
2016-02-09T17:56:16,0
2016-02-09T18:22:19,45
2016-02-09T18:27:51,0
2016-02-10T07:56:22,45
2016-02-10T08:07:48,0
2016-02-10T09:16:43,45
2016-02-10T09:30:15,0
2016-02-10T09:30:45,45
2016-02-10T09:33:04,0
2016-02-10T10:04:30,45
2016-02-10T10:48:02,0
2016-02-10T11:10:42,45
2016-02-10T11:53:31,0
2016-02-10T12:25:24,45
2016-02-10T12:32:36,0
2016-02-10T12:47:29,45
2016-02-10T12:51:12,0
2016-02-10T13:41:02,45
2016-02-10T14:34:29,0
2016-02-10T15:07:32,45
2016-02-10T15:14:39,0
2016-02-10T15:19:01,45
2016-02-10T15:36:00,0
2016-02-10T15:53:42,45
2016-02-10T15:55:01,0
2016-02-10T16:16:41,45
2016-02-10T16:39:27,0
2016-02-10T16:54:29,45
2016-02-10T17:22:41,0
2016-02-10T17:40:13,45
2016-02-10T17:42:57,0
2016-02-10T17:55:33,45
2016-02-10T18:31:57,0
2016-02-10T18:53:12,45
2016-02-10T18:57:47,0
2016-02-10T19:11:46,45
2016-02-10T19:35:11,0
2016-02-10T20:30:30,45
2016-02-10T20:32:29,0
2016-02-11T07:42:34,45
2016-02-11T08:15:21,0
2016-02-11T09:03:10,45
2016-02-11T10:00:30,0
2016-02-11T10:03:18,45
2016-02-11T10:13:23,0
2016-02-11T10:15:23,45
2016-02-11T10:20:16,0
2016-02-11T10:26:00,45
2016-02-11T10:29:48,0
2016-02-11T10:54:01,45
2016-02-11T10:58:46,0
2016-02-11T11:01:51,45
2016-02-11T11:03:06,0
2016-02-11T11:10:51,45
2016-02-11T11:13:31,0
2016-02-11T11:37:35,45
2016-02-11T11:39:56,0
2016-02-11T12:02:54,45
2016-02-11T12:14:28,0
2016-02-11T12:18:47,45
2016-02-11T12:32:26,0
2016-02-11T13:00:12,45
2016-02-11T13:22:27,0
2016-02-11T13:38:10,45
2016-02-11T13:59:13,0
2016-02-11T14:13:49,45
2016-02-11T14:20:28,0
2016-02-11T14:28:17,45
2016-02-11T14:36:05,0
2016-02-11T15:12:21,45
2016-02-11T16:03:09,0
2016-02-11T17:03:08,45
2016-02-11T17:42:51,0
2016-02-11T17:53:03,45
2016-02-11T17:55:32,0
2016-02-11T17:59:22,45
2016-02-11T18:47:55,0
2016-02-11T20:23:49,45
2016-02-11T20:28:11,0
2016-02-12T08:38:43,45
2016-02-12T09:30:16,0
2016-02-12T09:36:54,45
2016-02-12T09:44:37,0
2016-02-12T10:00:26,45
2016-02-12T10:03:29,0
2016-02-12T10:52:58,45
2016-02-12T11:47:30,0
2016-02-12T14:52:26,45
2016-02-12T14:55:06,0
2016-02-12T15:33:04,45
2016-02-12T15:34:29,0
2016-02-12T15:39:39,45
2016-02-12T15:58:50,0
2016-02-12T16:24:57,45
2016-02-12T17:04:49,0
2016-02-12T17:10:25,45
2016-02-12T17:32:48,0
2016-02-12T17:37:49,45
2016-02-12T17:49:40,0
2016-02-12T17:57:54,45
2016-02-12T18:19:05,0
2016-02-13T07:24:54,45
2016-02-13T07:29:11,0
2016-02-13T15:40:16,45
2016-02-13T16:01:12,0
2016-02-14T10:09:17,45
2016-02-14T10:30:48,0
2016-02-14T15:30:11,45
2016-02-14T17:05:02,0
2016-02-15T08:06:22,45
2016-02-15T08:14:23,0
2016-02-15T08:19:30,45
2016-02-15T08:47:19,0
2016-02-15T09:19:08,45
2016-02-15T10:44:30,0
2016-02-15T10:47:46,45
2016-02-15T10:49:06,0
2016-02-15T11:03:22,45
2016-02-15T11:09:27,0
2016-02-15T11:14:51,45
2016-02-15T11:40:49,0
2016-02-15T11:41:34,45
2016-02-15T11:45:27,0
2016-02-15T12:02:52,45
2016-02-15T12:07:18,0
2016-02-15T13:07:31,45
2016-02-15T13:17:25,0
2016-02-15T13:40:16,45
2016-02-15T13:44:25,0
2016-02-15T14:37:22,45
2016-02-15T15:11:41,0
2016-02-15T15:14:49,45
2016-02-15T16:56:52,0
2016-02-15T17:22:38,45
2016-02-15T17:30:56,0
2016-02-15T17:46:45,45
2016-02-15T17:51:21,0
2016-02-16T07:31:54,45
2016-02-16T07:49:25,0
2016-02-16T09:46:47,45
2016-02-16T10:18:27,0
2016-02-16T10:57:51,45
2016-02-16T11:41:07,0
2016-02-16T12:11:51,45
2016-02-16T12:49:30,0
2016-02-16T13:05:04,45
2016-02-16T13:13:57,0
2016-02-16T13:26:08,45
2016-02-16T13:26:53,0
2016-02-16T13:35:56,45
2016-02-16T15:11:14,0
2016-02-16T15:16:15,45
2016-02-16T15:36:22,0
2016-02-16T15:46:32,45
2016-02-16T16:10:42,0
2016-02-16T16:54:21,45
2016-02-16T17:30:19,0
2016-02-16T17:35:53,45
2016-02-16T17:52:59,0
2016-02-16T18:01:24,45
2016-02-16T18:21:57,0
2016-02-16T18:29:28,45
2016-02-16T18:33:31,0
2016-02-17T08:16:07,45
2016-02-17T08:52:52,0
2016-02-17T09:29:02,45
2016-02-17T10:16:37,0
2016-02-17T10:28:51,45
2016-02-17T10:47:20,0
2016-02-17T11:03:32,45
2016-02-17T11:17:07,0
2016-02-17T11:23:31,45
2016-02-17T11:29:28,0
2016-02-17T11:39:27,45
2016-02-17T11:51:06,0
2016-02-17T12:31:05,45
2016-02-17T12:38:20,0
2016-02-17T12:47:25,45
2016-02-17T12:53:03,0
2016-02-17T12:55:00,45
2016-02-17T12:58:20,0
2016-02-17T13:06:33,45
2016-02-17T13:26:45,0
2016-02-17T13:51:38,45
2016-02-17T14:04:01,0
2016-02-17T14:15:16,45
2016-02-17T14:16:50,0
2016-02-17T14:40:18,45
2016-02-17T14:59:17,0
2016-02-17T15:04:29,45
2016-02-17T16:06:59,0
2016-02-17T16:07:01,45
2016-02-17T16:39:02,0
2016-02-17T16:42:57,45
2016-02-17T17:12:29,0
2016-02-17T17:32:56,45
2016-02-17T17:46:53,0
2016-02-17T18:05:52,45
2016-02-17T18:06:17,0
2016-02-17T18:41:53,45
2016-02-17T18:54:35,0
2016-02-18T06:26:25,45
2016-02-18T06:36:19,0
2016-02-18T07:02:31,45
2016-02-18T07:06:49,0
2016-02-18T08:23:38,45
2016-02-18T08:24:19,0
2016-02-18T09:11:38,45
2016-02-18T09:33:08,0
2016-02-18T09:41:58,45
2016-02-18T09:49:27,0
2016-02-18T10:34:42,45
2016-02-18T10:50:16,0
2016-02-18T10:59:00,45
2016-02-18T11:54:57,0
2016-02-18T12:01:48,45
2016-02-18T12:13:32,0
2016-02-18T12:22:50,45
2016-02-18T12:27:43,0
2016-02-18T12:38:41,45
2016-02-18T13:49:33,0
2016-02-18T13:50:12,45
2016-02-18T13:53:18,0
2016-02-18T13:53:55,45
2016-02-18T13:54:36,0
2016-02-18T14:25:09,45
2016-02-18T14:58:23,0
2016-02-18T15:01:34,45
2016-02-18T15:03:28,0
2016-02-18T15:17:06,45
2016-02-18T16:39:12,0
2016-02-18T16:44:48,45
2016-02-18T17:07:20,0
2016-02-18T17:20:48,45
2016-02-18T18:18:05,0
2016-02-19T09:23:41,45
2016-02-19T09:29:59,0
2016-02-19T10:37:49,45
2016-02-19T10:39:25,0
2016-02-19T13:27:02,45
2016-02-19T13:46:57,0
2016-02-19T14:11:21,45
2016-02-19T14:34:02,0
2016-02-19T14:58:20,45
2016-02-19T15:05:25,0
2016-02-19T15:32:11,45
2016-02-19T16:40:13,0
2016-02-19T17:18:27,45
2016-02-19T17:20:29,0
2016-02-19T18:30:24,45
2016-02-19T18:35:07,0
2016-02-19T20:12:36,45
2016-02-19T20:19:41,0
2016-02-21T13:13:57,45
2016-02-21T13:27:39,0
2016-02-22T07:49:02,45
2016-02-22T07:54:35,0
2016-02-22T08:22:34,45
2016-02-22T08:45:59,0
2016-02-22T08:56:48,45
2016-02-22T09:03:47,0
2016-02-22T09:12:45,45
2016-02-22T10:47:18,0
2016-02-22T11:09:24,45
2016-02-22T11:11:02,0
2016-02-22T11:16:56,45
2016-02-22T11:24:05,0
2016-02-22T11:33:41,45
2016-02-22T11:58:58,0
2016-02-22T13:14:34,45
2016-02-22T13:24:44,0
2016-02-22T13:34:34,45
2016-02-22T13:47:31,0
2016-02-22T14:14:01,45
2016-02-22T14:23:51,0
2016-02-22T14:29:50,45
2016-02-22T14:32:18,0
2016-02-22T14:36:21,45
2016-02-22T15:32:51,0
2016-02-22T15:53:03,45
2016-02-22T16:18:21,0
2016-02-22T17:19:03,45
2016-02-22T17:40:26,0
2016-02-22T17:45:29,45
2016-02-22T18:45:51,0
2016-02-22T20:23:31,45
2016-02-22T20:39:06,0
2016-02-23T09:45:36,45
2016-02-23T09:48:02,0
2016-02-23T10:12:49,45
2016-02-23T11:18:17,0
2016-02-23T11:41:01,45
2016-02-23T11:44:26,0
2016-02-23T12:48:16,45
2016-02-23T12:49:51,0
2016-02-23T13:03:03,45
2016-02-23T13:07:19,0
2016-02-23T13:13:27,45
2016-02-23T13:13:54,0
2016-02-23T13:28:45,45
2016-02-23T13:33:45,0
2016-02-23T13:38:34,45
2016-02-23T13:46:50,0
2016-02-23T13:47:12,45
2016-02-23T13:54:34,0
2016-02-23T14:00:09,45
2016-02-23T14:03:02,0
2016-02-23T14:15:00,45
2016-02-23T14:23:47,0
2016-02-23T14:49:58,45
2016-02-23T16:38:08,0
2016-02-23T16:40:55,45
2016-02-23T17:08:54,0
2016-02-23T17:39:03,45
2016-02-23T17:42:22,0
2016-02-23T17:50:11,45
2016-02-23T18:23:12,0
2016-02-23T20:30:47,45
2016-02-23T20:35:28,0
2016-02-24T08:51:17,45
2016-02-24T09:03:03,0
2016-02-24T09:30:02,45
2016-02-24T09:42:17,0
2016-02-24T09:55:43,45
2016-02-24T10:08:22,0
2016-02-24T10:08:41,45
2016-02-24T10:44:17,0
2016-02-24T10:45:30,45
2016-02-24T11:26:51,0
2016-02-24T11:34:42,45
2016-02-24T11:55:42,0
2016-02-24T12:09:04,45
2016-02-24T12:10:14,0
2016-02-24T12:46:40,45
2016-02-24T12:49:26,0
2016-02-24T14:01:59,45
2016-02-24T14:45:10,0
2016-02-24T15:07:52,45
2016-02-24T15:12:49,0
2016-02-24T15:37:39,45
2016-02-24T15:59:11,0
2016-02-24T16:08:51,45
2016-02-24T16:54:03,0
2016-02-24T17:22:31,45
2016-02-24T17:28:25,0
2016-02-24T17:57:44,45
2016-02-24T18:15:56,0
2016-02-24T18:17:37,45
2016-02-24T18:20:44,0
2016-02-25T08:15:19,45
2016-02-25T08:33:40,0
2016-02-25T08:51:07,45
2016-02-25T08:57:46,0
2016-02-25T09:00:24,45
2016-02-25T09:19:59,0
2016-02-25T10:34:01,45
2016-02-25T10:55:56,0
2016-02-25T11:03:35,45
2016-02-25T11:06:12,0
2016-02-25T11:07:59,45
2016-02-25T11:30:14,0
2016-02-25T11:35:15,45
2016-02-25T11:44:02,0
2016-02-25T13:05:19,45
2016-02-25T13:07:04,0
2016-02-25T13:11:53,45
2016-02-25T13:24:47,0
2016-02-25T13:27:01,45
2016-02-25T13:27:20,0
2016-02-25T14:18:48,45
2016-02-25T14:39:58,0
2016-02-25T14:46:16,45
2016-02-25T14:46:37,0
2016-02-25T14:57:17,45
2016-02-25T15:18:34,0
2016-02-25T15:31:54,45
2016-02-25T16:06:52,0
2016-02-25T16:07:24,45
2016-02-25T16:23:43,0
2016-02-25T16:29:44,45
2016-02-25T17:04:07,0
2016-02-26T08:53:46,45
2016-02-26T09:17:27,0
2016-02-26T09:54:19,45
2016-02-26T09:58:05,0
2016-02-26T10:11:13,45
2016-02-26T10:38:26,0
2016-02-26T10:39:12,45
2016-02-26T11:16:12,0
2016-02-26T11:45:45,45
2016-02-26T11:55:29,0
2016-02-26T11:57:33,45
2016-02-26T12:03:08,0
2016-02-26T12:49:01,45
2016-02-26T12:54:09,0
2016-02-26T13:19:41,45
2016-02-26T14:52:45,0
2016-02-26T14:59:10,45
2016-02-26T15:30:51,0
2016-02-26T15:41:14,45
2016-02-26T15:57:29,0
2016-02-26T16:48:50,45
2016-02-26T16:50:30,0
2016-02-26T17:05:46,45
2016-02-26T17:27:09,0
2016-02-26T18:53:20,45
2016-02-26T18:58:44,0
2016-02-27T11:03:50,45
2016-02-27T11:14:00,0
2016-02-27T15:36:04,45
2016-02-27T15:57:42,0
2016-02-27T16:20:06,45
2016-02-27T16:26:09,0
2016-02-27T16:45:14,45
2016-02-27T16:56:01,0
2016-02-27T17:52:19,45
2016-02-27T18:22:03,0
2016-02-27T18:45:06,45
2016-02-27T19:17:34,0
2016-02-29T07:24:46,45
2016-02-29T07:57:12,0
2016-02-29T10:05:49,45
2016-02-29T10:08:48,0
2016-02-29T10:09:42,45
2016-02-29T10:44:11,0
2016-02-29T10:58:05,45
2016-02-29T11:19:36,0
2016-02-29T12:02:40,45
2016-02-29T12:06:39,0
2016-02-29T13:06:04,45
2016-02-29T13:14:25,0
2016-02-29T13:14:32,45
2016-02-29T13:38:10,0
2016-02-29T13:42:30,45
2016-02-29T14:09:30,0
2016-02-29T14:19:15,45
2016-02-29T14:19:37,0
2016-02-29T14:44:43,45
2016-02-29T15:08:31,0
2016-02-29T15:12:47,45
2016-02-29T15:55:03,0
2016-02-29T16:31:14,45
2016-02-29T16:32:19,0
2016-02-29T16:44:03,45
2016-02-29T17:10:03,0
2016-02-29T18:16:59,45
2016-02-29T18:26:39,0
2016-02-29T19:38:34,45
2016-02-29T19:38:43,0
2016-03-01T07:53:06,45
2016-03-01T08:28:20,0
2016-03-01T09:05:20,45
2016-03-01T09:12:44,0
2016-03-01T09:23:31,45
2016-03-01T09:49:51,0
2016-03-01T09:52:01,45
2016-03-01T09:52:29,0
2016-03-01T10:40:33,45
2016-03-01T10:45:17,0
2016-03-01T11:20:11,45
2016-03-01T11:23:26,0
2016-03-01T11:26:55,45
2016-03-01T11:37:00,0
2016-03-01T11:43:08,45
2016-03-01T12:02:48,0
2016-03-01T12:12:07,45
2016-03-01T12:27:14,0
2016-03-01T14:06:22,45
2016-03-01T14:15:50,0
2016-03-01T14:26:33,45
2016-03-01T14:30:51,0
2016-03-01T14:40:32,45
2016-03-01T15:05:58,0
2016-03-01T15:18:31,45
2016-03-01T15:23:51,0
2016-03-01T15:40:23,45
2016-03-01T16:39:55,0
2016-03-01T16:53:11,45
2016-03-01T16:59:58,0
2016-03-01T17:11:17,45
2016-03-01T17:22:56,0
2016-03-01T17:29:39,45
2016-03-01T17:38:01,0
2016-03-01T18:07:46,45
2016-03-01T18:17:39,0
2016-03-01T18:17:49,45
2016-
Download .txt
gitextract_u5aix2x9/

├── .check_external_deps.sh
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── actions/
│   │   ├── setup-poetry-env/
│   │   │   └── action.yml
│   │   └── setup-poetry-env-only-main/
│   │       └── action.yml
│   └── workflows/
│       ├── main.yml
│       ├── on-release-main.yml
│       └── validate-codecov-config.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .readthedocs.yaml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── codecov.yaml
├── docs/
│   ├── Makefile
│   ├── _templates/
│   │   └── side-primary.html
│   ├── _themes/
│   │   ├── LICENSE
│   │   └── ms/
│   │       ├── layout.html
│   │       ├── relations.html
│   │       ├── static/
│   │       │   ├── flasky.css_t
│   │       │   └── small_flask.css
│   │       └── theme.conf
│   ├── api_reference.rst
│   ├── conf.py
│   ├── examples.rst
│   ├── goals.rst
│   ├── index.rst
│   ├── merge_strategies.rst
│   ├── sorted_dict.rst
│   └── unevenly-spaced.rst
├── docs-md/
│   ├── index.md
│   ├── modules.md
│   └── stylesheets/
│       └── extra.css
├── examples/
│   ├── Plot.ipynb
│   ├── Shaded.ipynb
│   ├── Untitled.ipynb
│   ├── data/
│   │   ├── lightbulb-01.csv
│   │   ├── lightbulb-02.csv
│   │   ├── lightbulb-03.csv
│   │   ├── lightbulb-04.csv
│   │   ├── lightbulb-05.csv
│   │   ├── lightbulb-06.csv
│   │   ├── lightbulb-07.csv
│   │   ├── lightbulb-08.csv
│   │   ├── lightbulb-09.csv
│   │   ├── lightbulb-10.csv
│   │   ├── lightbulb-11.csv
│   │   ├── lightbulb-12.csv
│   │   ├── lightbulb-13.csv
│   │   ├── lightbulb-14.csv
│   │   ├── lightbulb-15.csv
│   │   ├── lightbulb-16.csv
│   │   ├── lightbulb-17.csv
│   │   ├── lightbulb-18.csv
│   │   ├── lightbulb-19.csv
│   │   ├── lightbulb-20.csv
│   │   ├── lightbulb-21.csv
│   │   ├── lightbulb-22.csv
│   │   ├── lightbulb-23.csv
│   │   ├── lightbulb-24.csv
│   │   ├── lightbulb-25.csv
│   │   ├── lightbulb-26.csv
│   │   ├── lightbulb-27.csv
│   │   ├── lightbulb-28.csv
│   │   ├── lightbulb-29.csv
│   │   ├── lightbulb-30.csv
│   │   ├── lightbulb-31.csv
│   │   ├── lightbulb-32.csv
│   │   ├── lightbulb-33.csv
│   │   ├── lightbulb-34.csv
│   │   ├── lightbulb-35.csv
│   │   ├── lightbulb-36.csv
│   │   ├── lightbulb-37.csv
│   │   ├── lightbulb-38.csv
│   │   ├── lightbulb-39.csv
│   │   └── lightbulb-40.csv
│   ├── event_analysis.py
│   ├── financial_analysis.py
│   ├── helloworld.py
│   ├── iot_sensor_analysis.py
│   ├── stackystack.py
│   ├── stackystack.py.bak
│   └── timing.py
├── experiments/
│   ├── bench_merge.py
│   ├── bench_merge_strategies.py
│   ├── bench_sorted_dict.py
│   ├── bench_tickets.py
│   └── sorted_dict_replacement.py
├── mkdocs.yml
├── poetry.toml
├── pyproject.toml
├── tests/
│   ├── .coveragerc
│   ├── __init__.py
│   ├── test_compact.py
│   ├── test_distribution.py
│   ├── test_distribution_external.py
│   ├── test_docs.py
│   ├── test_eventseries.py
│   ├── test_eventseries_external.py
│   ├── test_histogram.py
│   ├── test_histogram_external.py
│   ├── test_improved_methods.py
│   ├── test_iterators.py
│   ├── test_json_io.py
│   ├── test_methods.py
│   ├── test_methods_external.py
│   ├── test_missing.py
│   ├── test_operations.py
│   ├── test_plot.py
│   ├── test_plot_external.py
│   ├── test_something.py
│   ├── test_sorted_dict.py
│   ├── test_traces.py
│   ├── test_traces_external.py
│   └── test_utils.py
├── tox.ini
└── traces/
    ├── __init__.py
    ├── decorators.py
    ├── eventseries.py
    ├── histogram.py
    ├── infinity.py
    ├── operations.py
    ├── plot.py
    ├── sorted_dict.py
    ├── timeseries.py
    └── utils.py
Download .txt
SYMBOL INDEX (421 symbols across 42 files)

FILE: examples/event_analysis.py
  function hourly_counts (line 164) | def hourly_counts(event_series, start_time, end_time):

FILE: examples/financial_analysis.py
  function parse_datetime (line 19) | def parse_datetime(date_string):
  function create_price_series (line 43) | def create_price_series():
  function create_trading_hours_mask (line 67) | def create_trading_hours_mask(
  function calculate_vwap (line 118) | def calculate_vwap(price_ts, volume_ts):
  function calculate_returns (line 150) | def calculate_returns(price_ts):

FILE: examples/helloworld.py
  function parse_iso_datetime (line 9) | def parse_iso_datetime(value):
  function read_all (line 13) | def read_all(pattern="examples/data/lightbulb-*.csv"):

FILE: examples/iot_sensor_analysis.py
  function generate_sensor_data (line 20) | def generate_sensor_data(
  function cos_like (line 90) | def cos_like(hour, peak_hour=12):
  function cos_transform (line 95) | def cos_transform(x, period=24):
  function print_sensor_stats (line 119) | def print_sensor_stats(name, ts):
  function detect_threshold_crossings (line 156) | def detect_threshold_crossings(ts, threshold, rising=True):
  function detect_anomalies (line 200) | def detect_anomalies(ts, window_size=timedelta(hours=6), z_score_thresho...
  function resample_all_sensors (line 262) | def resample_all_sensors(start_time, end_time, interval=timedelta(minute...

FILE: examples/stackystack.py
  function average (line 7) | def average(values):
  class Test (line 17) | class Test(traces.TimeSeries):
    method stack (line 18) | def stack(self, duration, start_times, operation):
  function xmprint (line 32) | def xmprint(ts):
  function generate_ts (line 38) | def generate_ts(n_days):
  function hour_mask (line 55) | def hour_mask(n_days, hours):

FILE: examples/timing.py
  class timer (line 9) | class timer:
    method __call__ (line 10) | def __call__(self, function):
  function print_results (line 24) | def print_results(*args):
  function timing_loop (line 63) | def timing_loop(n, mod=1000):

FILE: experiments/bench_merge.py
  function make_boolean_timeseries_list (line 16) | def make_boolean_timeseries_list(k, n_transitions=2):
  function make_int_timeseries_list (line 29) | def make_int_timeseries_list(k, n_transitions=100):
  function bench (line 42) | def bench(label, func, repeat=3):
  function run_benchmarks (line 60) | def run_benchmarks():

FILE: experiments/bench_merge_strategies.py
  function naive_iter_merge (line 34) | def naive_iter_merge(timeseries_list):
  function naive_merge (line 51) | def naive_merge(ts_list, operation=None):
  function heapq_iter_merge_transitions (line 66) | def heapq_iter_merge_transitions(timeseries_list):
  function heapq_iter_merge (line 95) | def heapq_iter_merge(timeseries_list):
  function heapq_merge (line 115) | def heapq_merge(ts_list, operation=None):
  function make_boolean_ts_list (line 134) | def make_boolean_ts_list(k, n_per_series=2):
  function make_int_ts_list (line 147) | def make_int_ts_list(k, n_per_series=100):
  function bench (line 160) | def bench(label, func, repeat=3):
  function print_row (line 177) | def print_row(label, time_s, mem_kb):
  function run (line 181) | def run():

FILE: experiments/bench_sorted_dict.py
  function bench (line 24) | def bench(setup, stmt_local, stmt_sc, number=None, repeat=3):
  function fmt_time (line 40) | def fmt_time(t):
  function run_benchmarks (line 51) | def run_benchmarks():

FILE: experiments/bench_tickets.py
  function make_ticket_data (line 27) | def make_ticket_data(n_tickets):
  function approach_timeseries_merge_sum (line 37) | def approach_timeseries_merge_sum(tickets):
  function approach_timeseries_count_by_value (line 48) | def approach_timeseries_count_by_value(tickets):
  function approach_eventseries_count_active (line 60) | def approach_eventseries_count_active(tickets):
  function bench (line 67) | def bench(label, func, repeat=5):
  function run (line 85) | def run():

FILE: experiments/sorted_dict_replacement.py
  class DictTimeSeries (line 22) | class DictTimeSeries:
    method __init__ (line 25) | def __init__(self, data=None, default=None):
    method set_many (line 32) | def set_many(self, data):
    method set (line 39) | def set(self, time, value):
    method __setitem__ (line 46) | def __setitem__(self, time, value):
    method get (line 49) | def get(self, time):
    method __getitem__ (line 58) | def __getitem__(self, time):
    method __delitem__ (line 61) | def __delitem__(self, time):
    method __len__ (line 69) | def __len__(self):
    method __bool__ (line 72) | def __bool__(self):
    method __iter__ (line 75) | def __iter__(self):
    method items (line 78) | def items(self):
    method first_key (line 81) | def first_key(self):
    method last_key (line 84) | def last_key(self):
    method get_item_by_index (line 87) | def get_item_by_index(self, index):
    method iterperiods (line 93) | def iterperiods(self, start=None, end=None):
    method distribution (line 121) | def distribution(self, start=None, end=None):
    method set_interval (line 130) | def set_interval(self, start, end, value):
    method n_points (line 146) | def n_points(self, start=None, end=None):
    method compact (line 159) | def compact(self):
  class SortedDictTimeSeries (line 176) | class SortedDictTimeSeries:
    method __init__ (line 179) | def __init__(self, data=None, default=None):
    method set_many (line 183) | def set_many(self, data):
    method set (line 187) | def set(self, time, value):
    method __setitem__ (line 190) | def __setitem__(self, time, value):
    method get (line 193) | def get(self, time):
    method __getitem__ (line 202) | def __getitem__(self, time):
    method __delitem__ (line 205) | def __delitem__(self, time):
    method __len__ (line 208) | def __len__(self):
    method __bool__ (line 211) | def __bool__(self):
    method __iter__ (line 214) | def __iter__(self):
    method items (line 217) | def items(self):
    method first_key (line 220) | def first_key(self):
    method last_key (line 223) | def last_key(self):
    method get_item_by_index (line 226) | def get_item_by_index(self, index):
    method iterperiods (line 229) | def iterperiods(self, start=None, end=None):
    method distribution (line 254) | def distribution(self, start=None, end=None):
    method set_interval (line 261) | def set_interval(self, start, end, value):
    method n_points (line 268) | def n_points(self, start=None, end=None):
    method compact (line 275) | def compact(self):
  function merge_simple (line 291) | def merge_simple(ts_list, operation=None):
  function merge_pq (line 309) | def merge_pq(ts_list, operation=None):
  function verify_correctness (line 372) | def verify_correctness():
  function bench (line 450) | def bench(description, setup, stmt_dict, stmt_sorted, number=None, repea...
  function run_benchmarks (line 476) | def run_benchmarks():
  function bench_merge (line 689) | def bench_merge(
  function run_merge_benchmarks (line 715) | def run_merge_benchmarks():

FILE: tests/test_compact.py
  function test_compact (line 6) | def test_compact():

FILE: tests/test_distribution.py
  function test_distribution (line 8) | def test_distribution():
  function test_default_values (line 34) | def test_default_values():
  function test_mask (line 51) | def test_mask():
  function test_integer_times (line 86) | def test_integer_times():
  function test_distribution_set (line 100) | def test_distribution_set():
  function test_distribution_empty (line 111) | def test_distribution_empty():
  function test_none_handling (line 152) | def test_none_handling():
  function test_timestamp_range (line 163) | def test_timestamp_range():

FILE: tests/test_distribution_external.py
  function test_pandas_timestamp_range (line 6) | def test_pandas_timestamp_range():

FILE: tests/test_docs.py
  function test_quickstart (line 6) | def test_quickstart():
  function test_reference (line 24) | def test_reference():

FILE: tests/test_eventseries.py
  function test_init_data (line 4) | def test_init_data():
  function test_count_active (line 14) | def test_count_active():
  function test_cumulative_sum (line 28) | def test_cumulative_sum():
  function test_events_between (line 34) | def test_events_between():

FILE: tests/test_eventseries_external.py
  function test_cumsum (line 6) | def test_cumsum():
  function test_events_between (line 49) | def test_events_between():
  function test_time_lag (line 118) | def test_time_lag():

FILE: tests/test_histogram.py
  function test_normalize (line 4) | def test_normalize():
  function test_addition (line 12) | def test_addition():
  function test_minmax_with_zeros (line 20) | def test_minmax_with_zeros():
  function test_histogram_stats_with_nones (line 32) | def test_histogram_stats_with_nones():

FILE: tests/test_histogram_external.py
  function test_quantiles (line 8) | def test_quantiles():
  function _test_statistics (line 24) | def _test_statistics(normalized):
  function test_statistics (line 65) | def test_statistics():
  function test_normalized_statistics (line 69) | def test_normalized_statistics():
  function test_quantile_interpolation (line 73) | def test_quantile_interpolation():

FILE: tests/test_improved_methods.py
  class TestImprovedMethods (line 8) | class TestImprovedMethods:
    method test_exists_method_deprecation_warning (line 11) | def test_exists_method_deprecation_warning(self):
    method test_is_not_none_method (line 29) | def test_is_not_none_method(self):
    method test_is_not_none_with_default (line 44) | def test_is_not_none_with_default(self):
    method test_exists_matches_is_not_none (line 56) | def test_exists_matches_is_not_none(self):
  class TestStringRepresentation (line 75) | class TestStringRepresentation:
    method test_repr_shows_default (line 78) | def test_repr_shows_default(self):
    method test_str_shows_default (line 87) | def test_str_shows_default(self):
    method test_str_truncation (line 95) | def test_str_truncation(self):

FILE: tests/test_iterators.py
  function test_iterintervals (line 10) | def test_iterintervals():
  function test_iterperiods (line 24) | def test_iterperiods():
  function test_slice (line 76) | def test_slice():
  function make_random_timeseries (line 91) | def make_random_timeseries():
  function test_merge (line 102) | def test_merge():
  function test_single_merges (line 119) | def test_single_merges():
  function test_iter_merge_transitions_empty (line 168) | def test_iter_merge_transitions_empty():
  function test_iter_merge_transitions_single (line 172) | def test_iter_merge_transitions_single():
  function test_iter_merge_transitions_multiple (line 184) | def test_iter_merge_transitions_multiple():
  function test_iter_merge_transitions_tied_times (line 203) | def test_iter_merge_transitions_tied_times():
  function test_iter_merge_transitions_preserves_previous_value (line 217) | def test_iter_merge_transitions_preserves_previous_value():
  function test_count_by_value_empty (line 231) | def test_count_by_value_empty():
  function test_count_by_value_boolean (line 235) | def test_count_by_value_boolean():
  function test_count_by_value_multi_state (line 280) | def test_count_by_value_multi_state():
  function test_count_by_value_single_series (line 313) | def test_count_by_value_single_series():

FILE: tests/test_json_io.py
  class TestJsonIO (line 13) | class TestJsonIO:
    method test_to_json_list_format (line 16) | def test_to_json_list_format(self):
    method test_to_json_dict_format (line 33) | def test_to_json_dict_format(self):
    method test_to_json_with_custom_transform (line 47) | def test_to_json_with_custom_transform(self):
    method test_to_json_file_output (line 67) | def test_to_json_file_output(self):
    method test_from_json_list_format (line 99) | def test_from_json_list_format(self):
    method test_from_json_dict_format (line 114) | def test_from_json_dict_format(self):
    method test_from_json_with_custom_keys (line 127) | def test_from_json_with_custom_keys(self):
    method test_from_json_with_custom_transform (line 144) | def test_from_json_with_custom_transform(self):
    method test_from_json_file (line 175) | def test_from_json_file(self):
    method test_from_json_invalid_format (line 201) | def test_from_json_invalid_format(self):
    method test_from_json_missing_source (line 210) | def test_from_json_missing_source(self):
    method test_roundtrip_json (line 217) | def test_roundtrip_json(self):

FILE: tests/test_methods.py
  function _make_ts (line 34) | def _make_ts(type_, key_list, value_list):
  function frange (line 41) | def frange(x, y, jump):
  function test_mean (line 47) | def test_mean():
  function test_mean_interpolate (line 69) | def test_mean_interpolate():
  function test_sample (line 90) | def test_sample():
  function test_moving_average (line 139) | def test_moving_average():
  function test_to_bool (line 226) | def test_to_bool():
  function test_get_item_by_index (line 239) | def test_get_item_by_index():
  function test_bin (line 254) | def test_bin():
  function test_rebin (line 286) | def test_rebin():
  function test_npoints (line 290) | def test_npoints():
  function test_radd (line 331) | def test_radd():
  function test_repr (line 351) | def test_repr():

FILE: tests/test_methods_external.py
  function test_sample_pandas_compatibility (line 7) | def test_sample_pandas_compatibility():
  function test_moving_average_pandas_compatibility (line 14) | def test_moving_average_pandas_compatibility():
  function test_moving_average_pandas_flag (line 22) | def test_moving_average_pandas_flag():

FILE: tests/test_missing.py
  function test_missing (line 6) | def test_missing():

FILE: tests/test_operations.py
  function test_scalar_ops (line 9) | def test_scalar_ops():
  function test_sum (line 44) | def test_sum():
  function test_interpolation (line 87) | def test_interpolation():
  function test_default (line 102) | def test_default():
  function test_difference (line 114) | def test_difference():
  function test_to_bool_default (line 122) | def test_to_bool_default():
  function test_truthiness (line 170) | def test_truthiness():
  function test_logical_operations (line 179) | def test_logical_operations():

FILE: tests/test_plot.py
  function _make_ts (line 10) | def _make_ts():
  function test_message_when_matplotlib_not_installed (line 17) | def test_message_when_matplotlib_not_installed():

FILE: tests/test_plot_external.py
  function test_plot (line 12) | def test_plot():
  function test_invalid_call (line 23) | def test_invalid_call():
  function test_empty (line 35) | def test_empty():

FILE: tests/test_something.py
  function test_compact (line 6) | def test_compact():
  function test_remove (line 27) | def test_remove():
  function test_last_item (line 47) | def test_last_item():

FILE: tests/test_sorted_dict.py
  function test_insert_maintains_sorted_order (line 4) | def test_insert_maintains_sorted_order():
  function test_overwrite_does_not_duplicate_key (line 14) | def test_overwrite_does_not_duplicate_key():
  function test_delete (line 23) | def test_delete():
  function test_update_from_dict (line 31) | def test_update_from_dict():
  function test_update_from_sorted_dict (line 38) | def test_update_from_sorted_dict():
  function test_update_from_pairs (line 45) | def test_update_from_pairs():
  function test_init_from_dict (line 51) | def test_init_from_dict():
  function test_peekitem (line 56) | def test_peekitem():
  function test_bisect (line 63) | def test_bisect():
  function test_irange_inclusive (line 71) | def test_irange_inclusive():
  function test_delete_range (line 79) | def test_delete_range():
  function test_delete_range_exclusive (line 86) | def test_delete_range_exclusive():
  function test_islice (line 92) | def test_islice():
  function test_empty (line 98) | def test_empty():
  function test_bool (line 106) | def test_bool():
  function test_eq (line 113) | def test_eq():
  function test_repr (line 119) | def test_repr():

FILE: tests/test_traces.py
  function test_init_data (line 11) | def test_init_data():
  function test_get (line 43) | def test_get():
  function test_exists (line 56) | def test_exists():
  function test_merge (line 66) | def test_merge():
  function test_set_interval (line 80) | def test_set_interval():
  function test_set_interval_datetime (line 130) | def test_set_interval_datetime():
  function test_remove_points_from_interval (line 143) | def test_remove_points_from_interval():
  function test_pickle (line 170) | def test_pickle():
  function test_csv (line 182) | def test_csv():
  function test_set_same_interval_twice (line 239) | def test_set_same_interval_twice():
  function test_set_many_from_pairs (line 249) | def test_set_many_from_pairs():
  function test_set_many_from_dict (line 255) | def test_set_many_from_dict():
  function test_set_many_merges_with_existing (line 261) | def test_set_many_merges_with_existing():
  function test_set_many_overwrites (line 267) | def test_set_many_overwrites():
  function test_set_many_equivalent_to_init (line 274) | def test_set_many_equivalent_to_init():
  function test_convenience_access_methods (line 282) | def test_convenience_access_methods():

FILE: tests/test_traces_external.py
  function test_csv (line 12) | def test_csv():
  function test_sample_interval_days (line 32) | def test_sample_interval_days():
  function test_sample_interval_hours (line 76) | def test_sample_interval_hours():
  function test_sample_interval_index (line 122) | def test_sample_interval_index():

FILE: tests/test_utils.py
  function test_duration_to_number (line 20) | def test_duration_to_number():
  function test_convert_args_to_list (line 35) | def test_convert_args_to_list():
  function test_datetime_range (line 79) | def test_datetime_range():
  function test_datetime_floor (line 126) | def test_datetime_floor():
  function test_weekday_number (line 162) | def test_weekday_number():

FILE: traces/decorators.py
  function _is_none (line 5) | def _is_none(obj):
  function ignorant (line 9) | def ignorant(func):
  function strict (line 18) | def strict(func):

FILE: traces/eventseries.py
  class EventSeries (line 15) | class EventSeries(list):
    method __init__ (line 54) | def __init__(self, data=None):
    method append (line 65) | def append(self, value):
    method extend (line 69) | def extend(self, values):
    method bisect_left (line 74) | def bisect_left(self, value):
    method bisect_right (line 78) | def bisect_right(self, value):
    method cumsum (line 82) | def cumsum(self):
    method cumulative_sum (line 90) | def cumulative_sum(self):
    method events_between (line 121) | def events_between(self, start, end):
    method iter_interevent_times (line 147) | def iter_interevent_times(self):
    method count_active (line 177) | def count_active(es_open, es_closed):

FILE: traces/histogram.py
  class UnorderableElements (line 6) | class UnorderableElements(TypeError):
  class UnhashableType (line 10) | class UnhashableType(TypeError):
  class Histogram (line 14) | class Histogram:
    method from_dict (line 16) | def from_dict(cls, in_dict):
    method __init__ (line 22) | def __init__(self, data=()):
    method _use_unsorted (line 28) | def _use_unsorted(self):
    method __getitem__ (line 32) | def __getitem__(self, key):
    method __setitem__ (line 45) | def __setitem__(self, key, value):
    method __contains__ (line 62) | def __contains__(self, key):
    method __len__ (line 65) | def __len__(self):
    method __bool__ (line 68) | def __bool__(self):
    method __iter__ (line 71) | def __iter__(self):
    method __eq__ (line 74) | def __eq__(self, other):
    method __ne__ (line 79) | def __ne__(self, other):
    method keys (line 85) | def keys(self):
    method values (line 90) | def values(self):
    method items (line 95) | def items(self):
    method total (line 100) | def total(self):
    method _prepare_for_stats (line 104) | def _prepare_for_stats(self):
    method mean (line 110) | def mean(self):
    method variance (line 119) | def variance(self):
    method standard_deviation (line 131) | def standard_deviation(self):
    method normalized (line 139) | def normalized(self):
    method _discard_value (line 150) | def _discard_value(self, value):
    method max (line 158) | def max(self, include_zero=False):
    method min (line 165) | def min(self, include_zero=False):
    method _quantile_function (line 172) | def _quantile_function(self, alpha=0.5, smallest_count=None):  # noqa:...
    method median (line 249) | def median(self, alpha=0.5, smallest_count=None):
    method quantiles (line 252) | def quantiles(self, q_list, alpha=0.5, smallest_count=None):
    method quantile (line 256) | def quantile(self, q, alpha=0.5, smallest_count=None):
    method add (line 263) | def add(self, other):

FILE: traces/infinity.py
  class Infinity (line 40) | class Infinity:
    method __init__ (line 41) | def __init__(self, positive=True):
    method __neg__ (line 44) | def __neg__(self):
    method __gt__ (line 47) | def __gt__(self, other):
    method __eq__ (line 52) | def __eq__(self, other):
    method __ne__ (line 62) | def __ne__(self, other):
    method __bool__ (line 65) | def __bool__(self):
    method __nonzero__ (line 68) | def __nonzero__(self):
    method __str__ (line 71) | def __str__(self):
    method __float__ (line 74) | def __float__(self):
    method __add__ (line 77) | def __add__(self, other):
    method __radd__ (line 82) | def __radd__(self, other):
    method __sub__ (line 85) | def __sub__(self, other):
    method __rsub__ (line 90) | def __rsub__(self, other):
    method timetuple (line 93) | def timetuple(self):
    method __abs__ (line 96) | def __abs__(self):
    method __pos__ (line 99) | def __pos__(self):
    method __div__ (line 102) | def __div__(self, other):
    method __rdiv__ (line 110) | def __rdiv__(self, other):
    method __repr__ (line 113) | def __repr__(self):
    method __mul__ (line 121) | def __mul__(self, other):
    method __pow__ (line 130) | def __pow__(self, other):
    method __rpow__ (line 138) | def __rpow__(self, other):
    method __hash__ (line 146) | def __hash__(self):
  function is_infinite (line 153) | def is_infinite(value):

FILE: traces/operations.py
  function ignorant_sum (line 5) | def ignorant_sum(*args, **kwargs):
  function strict_sum (line 10) | def strict_sum(*args, **kwargs):

FILE: traces/plot.py
  function plot (line 50) | def plot(

FILE: traces/sorted_dict.py
  class SortedDict (line 11) | class SortedDict:
    method __init__ (line 20) | def __init__(self, data=None):
    method update (line 26) | def update(self, data):
    method __getitem__ (line 33) | def __getitem__(self, key):
    method __setitem__ (line 36) | def __setitem__(self, key, value):
    method __delitem__ (line 41) | def __delitem__(self, key):
    method __contains__ (line 46) | def __contains__(self, key):
    method __len__ (line 49) | def __len__(self):
    method __bool__ (line 52) | def __bool__(self):
    method __iter__ (line 55) | def __iter__(self):
    method __eq__ (line 58) | def __eq__(self, other):
    method __repr__ (line 63) | def __repr__(self):
    method keys (line 67) | def keys(self):
    method values (line 71) | def values(self):
    method items (line 74) | def items(self):
    method peekitem (line 81) | def peekitem(self, index=-1):
    method bisect_left (line 86) | def bisect_left(self, key):
    method bisect_right (line 89) | def bisect_right(self, key):
    method islice (line 92) | def islice(self, start=None, stop=None):
    method _range_indices (line 96) | def _range_indices(self, minimum, maximum, inclusive=(True, True)):
    method delete_range (line 109) | def delete_range(self, minimum, maximum, inclusive=(True, True)):
    method irange (line 125) | def irange(self, minimum, maximum, inclusive=(True, True)):

FILE: traces/timeseries.py
  class TimeSeries (line 20) | class TimeSeries:
    method __init__ (line 47) | def __init__(self, data=None, default=None):
    method __getstate__ (line 51) | def __getstate__(self):
    method __setstate__ (line 57) | def __setstate__(self, state):
    method __iter__ (line 60) | def __iter__(self):
    method __bool__ (line 64) | def __bool__(self):
    method is_empty (line 67) | def is_empty(self):
    method linear_interpolate (line 71) | def linear_interpolate(v0, v1, t):
    method scaled_time (line 75) | def scaled_time(t0, t1, time):
    method _get_linear_interpolate (line 78) | def _get_linear_interpolate(self, time):
    method _get_previous (line 91) | def _get_previous(self, time):
    method get (line 112) | def get(self, time, interpolate="previous"):
    method get_item_by_index (line 154) | def get_item_by_index(self, index):
    method last_item (line 158) | def last_item(self):
    method last_key (line 162) | def last_key(self):
    method last_value (line 166) | def last_value(self):
    method first_item (line 170) | def first_item(self):
    method first_key (line 174) | def first_key(self):
    method first_value (line 178) | def first_value(self):
    method set (line 182) | def set(self, time, value, compact=False):
    method set_many (line 194) | def set_many(self, data, compact=False):
    method set_interval (line 224) | def set_interval(self, start, end, value, compact=False):
    method compact (line 273) | def compact(self):
    method items (line 300) | def items(self):
    method exists (line 304) | def exists(self):
    method is_not_none (line 330) | def is_not_none(self):
    method remove (line 356) | def remove(self, time):
    method remove_points_from_interval (line 367) | def remove_points_from_interval(self, start, end):
    method n_measurements (line 390) | def n_measurements(self):
    method __len__ (line 394) | def __len__(self):
    method __repr__ (line 398) | def __repr__(self):
    method __str__ (line 412) | def __str__(self):
    method iterintervals (line 450) | def iterintervals(self, n=2):
    method _value_function (line 475) | def _value_function(value):
    method iterperiods (line 499) | def iterperiods(self, start=None, end=None, value=None):
    method slice (line 542) | def slice(self, start, end):
    method _check_regularization (line 559) | def _check_regularization(self, start, end, sampling_period=None):
    method sample (line 592) | def sample(
    method sample_interval (line 616) | def sample_interval(  # noqa: C901
    method moving_average (line 747) | def moving_average(  # noqa: C901
    method rebin (line 820) | def rebin(binned, key_function):
    method bin (line 831) | def bin(
    method mean (line 868) | def mean(self, start=None, end=None, mask=None, interpolate="previous"):
    method distribution (line 877) | def distribution(
    method n_points (line 939) | def n_points(
    method _check_time_series (line 997) | def _check_time_series(self, other):
    method iter_merge_transitions (line 1007) | def iter_merge_transitions(timeseries_list):
    method iter_merge (line 1049) | def iter_merge(cls, timeseries_list):
    method merge (line 1080) | def merge(cls, ts_list, compact=True, operation=None):
    method _flush_pending (line 1102) | def _flush_pending(pending, t, counts, result_data):
    method count_by_value (line 1110) | def count_by_value(cls, ts_list):
    method from_csv (line 1173) | def from_csv(
    method from_json (line 1242) | def from_json(
    method to_json (line 1335) | def to_json(
    method operation (line 1399) | def operation(self, other, function, default=None):
    method to_bool (line 1430) | def to_bool(self, invert=False, default=NotGiven):
    method threshold (line 1469) | def threshold(self, value, inclusive=False):
    method sum (line 1490) | def sum(self, other):
    method difference (line 1499) | def difference(self, other):
    method multiply (line 1503) | def multiply(self, other):
    method logical_and (line 1507) | def logical_and(self, other):
    method logical_or (line 1511) | def logical_or(self, other):
    method logical_xor (line 1515) | def logical_xor(self, other):
    method __setitem__ (line 1519) | def __setitem__(self, time, value):
    method __getitem__ (line 1526) | def __getitem__(self, time):
    method __delitem__ (line 1534) | def __delitem__(self, time):
    method __add__ (line 1541) | def __add__(self, other):
    method __radd__ (line 1545) | def __radd__(self, other):
    method __sub__ (line 1557) | def __sub__(self, other):
    method __mul__ (line 1561) | def __mul__(self, other):
    method __and__ (line 1565) | def __and__(self, other):
    method __or__ (line 1569) | def __or__(self, other):
    method __xor__ (line 1573) | def __xor__(self, other):
    method __invert__ (line 1577) | def __invert__(self):
    method __eq__ (line 1581) | def __eq__(self, other):
    method __ne__ (line 1584) | def __ne__(self, other):
    method _check_boundary (line 1587) | def _check_boundary(self, value, allow_infinite, lower_or_upper):
    method _check_boundaries (line 1616) | def _check_boundaries(self, start, end, mask=None, allow_infinite=False):
    method distribution_by_hour_of_day (line 1641) | def distribution_by_hour_of_day(
    method distribution_by_day_of_week (line 1653) | def distribution_by_day_of_week(
    method plot (line 1665) | def plot(
  function hour_of_day (line 1733) | def hour_of_day(start, end, hour):
  function day_of_week (line 1751) | def day_of_week(start, end, weekday):

FILE: traces/utils.py
  function duration_to_number (line 8) | def duration_to_number(duration, units="seconds"):
  function time_midpoint (line 32) | def time_midpoint(t0, t1):
  function convert_args_to_list (line 42) | def convert_args_to_list(args):
  function datetime_range (line 76) | def datetime_range(start_dt, end_dt, unit, n_units=1, inclusive_end=False):
  function floor_datetime (line 91) | def floor_datetime(dt, unit, n_units=1):
  function datetime_floor (line 131) | def datetime_floor(value, unit="days", n_units=1):
  function weekday_number (line 158) | def weekday_number(value):
  function pairwise (line 179) | def pairwise(iterable):
Copy disabled (too large) Download .json
Condensed preview — 129 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (17,952K chars).
[
  {
    "path": ".check_external_deps.sh",
    "chars": 615,
    "preview": "#!/bin/sh\n\n# write all imports that are in non-external-named test files\ngrep \"import \" tests/*.py | grep -v \"external\" "
  },
  {
    "path": ".editorconfig",
    "chars": 68,
    "preview": "max_line_length = 80\n\n[*.json]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 196,
    "preview": "- Simplicity is better than functionality\n- The API matters most, everything else is secondary\n\nFor feature requests, pl"
  },
  {
    "path": ".github/actions/setup-poetry-env/action.yml",
    "chars": 584,
    "preview": "name: \"setup-poetry-env\"\ndescription: \"Composite action to setup the Python and poetry environment.\"\n\ninputs:\n  python-v"
  },
  {
    "path": ".github/actions/setup-poetry-env-only-main/action.yml",
    "chars": 596,
    "preview": "name: \"setup-poetry-env\"\ndescription: \"Composite action to setup the Python and poetry environment.\"\n\ninputs:\n  python-v"
  },
  {
    "path": ".github/workflows/main.yml",
    "chars": 2312,
    "preview": "name: Main\n\non:\n  push:\n    branches:\n      - main\n      - dev\n  pull_request:\n    types: [opened, synchronize, reopened"
  },
  {
    "path": ".github/workflows/on-release-main.yml",
    "chars": 1025,
    "preview": "name: release-main\n\non:\n  release:\n    types: [published]\n    branches: [main]\n\njobs:\n  publish:\n    runs-on: ubuntu-lat"
  },
  {
    "path": ".github/workflows/validate-codecov-config.yml",
    "chars": 352,
    "preview": "name: validate-codecov-config\n\non:\n  pull_request:\n    paths: [codecov.yaml]\n  push:\n    branches: [main]\n\njobs:\n  valid"
  },
  {
    "path": ".gitignore",
    "chars": 3904,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 539,
    "preview": "repos:\n  - repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: \"v4.4.0\"\n    hooks:\n      - id: check-case-conf"
  },
  {
    "path": ".readthedocs.yaml",
    "chars": 343,
    "preview": "version: 2\n\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.12\"\n  jobs:\n    post_install:\n      - pip install poetry\n "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 1166,
    "preview": "# Changelog\n\n## [0.6.5] - In Development\n\n### Added\n\n- Added JSON import/export functionality:\n  - `TimeSeries.from_json"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4079,
    "preview": "# Authors\n\nCreated by [Mike Stringer](https://github.com/stringertheory/), [Vlad Seghete](https://github.com/vlsd/), and"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "\nMIT License\n\nCopyright (c) 2016, Mike Stringer\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "Makefile",
    "chars": 1959,
    "preview": ".PHONY: install\ninstall: ## Install the poetry environment and install the pre-commit hooks\n\t@echo \"🚀 Creating virtual e"
  },
  {
    "path": "README.md",
    "chars": 5307,
    "preview": "<!-- [![Version](https://img.shields.io/pypi/v/traces.svg?)](https://pypi.python.org/pypi/traces) -->\n<!-- [![PyVersions"
  },
  {
    "path": "codecov.yaml",
    "chars": 138,
    "preview": "coverage:\n  range: 70..100\n  round: down\n  precision: 1\n  status:\n    project:\n      default:\n        target: 90%\n      "
  },
  {
    "path": "docs/Makefile",
    "chars": 7606,
    "preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD "
  },
  {
    "path": "docs/_templates/side-primary.html",
    "chars": 1080,
    "preview": "<p class=\"logo\">\n  <a href=\"{{ pathto(master_doc) }}\"\n    ><img class=\"logo\" src=\"{{ pathto('_static/img/logo.png', 1) }"
  },
  {
    "path": "docs/_themes/LICENSE",
    "chars": 1895,
    "preview": "Modifications:\n\nCopyright (c) 2010 Kenneth Reitz.\nCopyright (c) 2016 Mike Stringer.\n\n\nOriginal Project:\n\nCopyright (c) 2"
  },
  {
    "path": "docs/_themes/ms/layout.html",
    "chars": 682,
    "preview": "{%- extends \"basic/layout.html\" %} {%- block extrahead %} {{ super() }} {% if\ntheme_touch_icon %}\n<link\n  rel=\"apple-tou"
  },
  {
    "path": "docs/_themes/ms/relations.html",
    "chars": 850,
    "preview": "<h3>Related Topics</h3>\n<ul>\n  <li>\n    <a href=\"{{ pathto(master_doc) }}\">Documentation overview</a>\n    <ul>\n      {%-"
  },
  {
    "path": "docs/_themes/ms/static/flasky.css_t",
    "chars": 7156,
    "preview": "/*\n * flasky.css_t\n * ~~~~~~~~~~~~\n *\n * :copyright: Copyright 2010 by Armin Ronacher. Modifications by Kenneth Reitz.\n "
  },
  {
    "path": "docs/_themes/ms/static/small_flask.css",
    "chars": 1080,
    "preview": "/*\n * small_flask.css_t\n * ~~~~~~~~~~~~~~~~~\n *\n * :copyright: Copyright 2010 by Armin Ronacher.\n * :license: Flask Desi"
  },
  {
    "path": "docs/_themes/ms/theme.conf",
    "chars": 121,
    "preview": "[theme]\ninherit = basic\nstylesheet = flasky.css\npygments_style = flask_theme_support.FlaskyStyle\n\n[options]\ntouch_icon ="
  },
  {
    "path": "docs/api_reference.rst",
    "chars": 3599,
    "preview": ".. _api:\n\nAPI Reference\n=============\n\n.. _timeseries:\n\nTimeSeries\n----------\n\nIn traces, a TimeSeries is similar to a d"
  },
  {
    "path": "docs/conf.py",
    "chars": 4603,
    "preview": "#\n# traces documentation build configuration file, created by\n# sphinx-quickstart\n#\n# This file is execfile()d with the "
  },
  {
    "path": "docs/examples.rst",
    "chars": 3720,
    "preview": ".. _examples:\n\nExamples\n========\n\n.. include:: goals.rst\n\nThis section has a few examples of how to do these things.\n\nRe"
  },
  {
    "path": "docs/goals.rst",
    "chars": 401,
    "preview": "Traces aims to make it simple to write *readable code* to:\n\n- **Wrangle**. Read, write, and manipulate unevenly-spaced t"
  },
  {
    "path": "docs/index.rst",
    "chars": 5416,
    "preview": ".. traces documentation master file, created by\n   sphinx-quickstart on Tue Sep 20 09:46:11 2016.\n   You can adapt this "
  },
  {
    "path": "docs/merge_strategies.rst",
    "chars": 17232,
    "preview": ".. _merge_strategies:\n\nMerge implementation strategies\n===============================\n\nMerging multiple TimeSeries is o"
  },
  {
    "path": "docs/sorted_dict.rst",
    "chars": 4157,
    "preview": ".. _sorted_dict:\n\nInternal sorted dictionary\n==========================\n\nTraces uses an internal ``SortedDict`` class (i"
  },
  {
    "path": "docs/unevenly-spaced.rst",
    "chars": 5511,
    "preview": "# Unevenly Spaced Data\n\nSeptember 26, 2016\n\nAs the Internet of Things (IoT) comes of age, we’re seeing more and more dat"
  },
  {
    "path": "docs-md/index.md",
    "chars": 16,
    "preview": "# boodle doodle\n"
  },
  {
    "path": "docs-md/modules.md",
    "chars": 78,
    "preview": "::: traces.timeseries\n\n::: traces.timeseries.TimeSeries\n:docstring:\n:members:\n"
  },
  {
    "path": "docs-md/stylesheets/extra.css",
    "chars": 71,
    "preview": ":root > * {\n  --md-mermaid-label-bg-color: rgba(255, 255, 255, 0.9);\n}\n"
  },
  {
    "path": "examples/Plot.ipynb",
    "chars": 12891,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n "
  },
  {
    "path": "examples/Shaded.ipynb",
    "chars": 22506,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n "
  },
  {
    "path": "examples/Untitled.ipynb",
    "chars": 72,
    "preview": "{\n \"cells\": [],\n \"metadata\": {},\n \"nbformat\": 4,\n \"nbformat_minor\": 4\n}\n"
  },
  {
    "path": "examples/data/lightbulb-01.csv",
    "chars": 38552,
    "preview": "time,watts\r\n2016-01-01T06:31:41,45\r\n2016-01-01T07:04:42,0\r\n2016-01-01T07:09:25,45\r\n2016-01-01T07:12:56,0\r\n2016-01-01T07:"
  },
  {
    "path": "examples/data/lightbulb-02.csv",
    "chars": 38763,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:47:33,45\r\n2016-01-01T08:55:18,0\r\n2016-01-01T10:00:48,45\r\n2016-01-01T10:"
  },
  {
    "path": "examples/data/lightbulb-03.csv",
    "chars": 39045,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:07:38,60\r\n2016-01-01T08:14:37,0\r\n2016-01-01T08:24:05,60\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-04.csv",
    "chars": 38575,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:23:42,45\r\n2016-01-01T08:29:18,0\r\n2016-01-01T08:42:39,45\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-05.csv",
    "chars": 2467676,
    "preview": "time,watts\r\n2016-01-01T00:00:00,0\r\n2016-01-01T00:01:00,0\r\n2016-01-01T00:02:00,0\r\n2016-01-01T00:03:00,0\r\n2016-01-01T00:04"
  },
  {
    "path": "examples/data/lightbulb-06.csv",
    "chars": 38904,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:47:35,45\r\n2016-01-01T09:06:38,0\r\n2016-01-01T09:37:20,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-07.csv",
    "chars": 40972,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:09:58,45\r\n2016-01-01T08:22:46,0\r\n2016-01-01T09:24:50,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-08.csv",
    "chars": 42053,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:22:46,60\r\n2016-01-01T08:56:56,0\r\n2016-01-01T09:25:51,60\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-09.csv",
    "chars": 37776,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:04:42,45\r\n2016-01-01T07:09:25,0\r\n2016-01-01T07:58:44,45\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-10.csv",
    "chars": 38575,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:45:27,60\r\n2016-01-01T07:47:46,0\r\n2016-01-01T08:39:02,60\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-11.csv",
    "chars": 38152,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:08:52,60\r\n2016-01-01T08:28:52,0\r\n2016-01-01T09:28:52,60\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-12.csv",
    "chars": 41160,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:45:02,60\r\n2016-01-01T09:58:31,0\r\n2016-01-01T10:09:02,60\r\n2016-01-01T10:"
  },
  {
    "path": "examples/data/lightbulb-13.csv",
    "chars": 38904,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:26:41,45\r\n2016-01-01T07:45:27,0\r\n2016-01-01T07:59:59,45\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-14.csv",
    "chars": 40267,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T09:00:29,60\r\n2016-01-01T09:38:50,0\r\n2016-01-01T11:01:17,60\r\n2016-01-01T11:"
  },
  {
    "path": "examples/data/lightbulb-15.csv",
    "chars": 38810,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T09:14:53,45\r\n2016-01-01T09:19:41,0\r\n2016-01-01T09:24:44,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-16.csv",
    "chars": 2466302,
    "preview": "time,watts\r\n2016-01-01T00:00:00,0\r\n2016-01-01T00:01:00,0\r\n2016-01-01T00:02:00,0\r\n2016-01-01T00:03:00,0\r\n2016-01-01T00:04"
  },
  {
    "path": "examples/data/lightbulb-17.csv",
    "chars": 41348,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T09:34:34,45\r\n2016-01-01T09:40:12,0\r\n2016-01-01T09:58:31,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-18.csv",
    "chars": 41113,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:49:33,45\r\n2016-01-01T09:18:06,0\r\n2016-01-01T09:53:10,45\r\n2016-01-01T10:"
  },
  {
    "path": "examples/data/lightbulb-19.csv",
    "chars": 40455,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:35:28,60\r\n2016-01-01T08:50:33,0\r\n2016-01-01T09:31:10,60\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-20.csv",
    "chars": 38998,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:22:57,45\r\n2016-01-01T07:23:42,0\r\n2016-01-01T08:35:21,45\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-21.csv",
    "chars": 2467040,
    "preview": "time,watts\r\n2016-01-01T00:00:00,0\r\n2016-01-01T00:01:00,0\r\n2016-01-01T00:02:00,0\r\n2016-01-01T00:03:00,0\r\n2016-01-01T00:04"
  },
  {
    "path": "examples/data/lightbulb-22.csv",
    "chars": 39750,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:37:14,60\r\n2016-01-01T09:02:15,0\r\n2016-01-01T09:19:41,60\r\n2016-01-01T10:"
  },
  {
    "path": "examples/data/lightbulb-23.csv",
    "chars": 36789,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:33:44,60\r\n2016-01-01T08:35:28,0\r\n2016-01-01T09:10:17,60\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-24.csv",
    "chars": 39280,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:02:16,60\r\n2016-01-01T08:08:52,0\r\n2016-01-01T09:21:23,60\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-25.csv",
    "chars": 41818,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:15:35,45\r\n2016-01-01T08:34:31,0\r\n2016-01-01T09:02:57,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-26.csv",
    "chars": 39797,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:55:56,45\r\n2016-01-01T07:58:44,0\r\n2016-01-01T09:33:30,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-27.csv",
    "chars": 37588,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:12:56,60\r\n2016-01-01T07:22:57,0\r\n2016-01-01T08:29:39,60\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-28.csv",
    "chars": 38622,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T09:21:24,60\r\n2016-01-01T09:28:28,0\r\n2016-01-01T10:29:20,60\r\n2016-01-01T10:"
  },
  {
    "path": "examples/data/lightbulb-29.csv",
    "chars": 40408,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T09:12:11,60\r\n2016-01-01T09:14:53,0\r\n2016-01-01T09:18:06,60\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-30.csv",
    "chars": 2467318,
    "preview": "time,watts\r\n2016-01-01T00:00:00,0\r\n2016-01-01T00:01:00,0\r\n2016-01-01T00:02:00,0\r\n2016-01-01T00:03:00,0\r\n2016-01-01T00:04"
  },
  {
    "path": "examples/data/lightbulb-31.csv",
    "chars": 2466799,
    "preview": "time,watts\r\n2016-01-01T00:00:00,0\r\n2016-01-01T00:01:00,0\r\n2016-01-01T00:02:00,0\r\n2016-01-01T00:03:00,0\r\n2016-01-01T00:04"
  },
  {
    "path": "examples/data/lightbulb-32.csv",
    "chars": 39750,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:53:19,60\r\n2016-01-01T07:59:59,0\r\n2016-01-01T08:17:32,60\r\n2016-01-01T08:"
  },
  {
    "path": "examples/data/lightbulb-33.csv",
    "chars": 40455,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:55:38,45\r\n2016-01-01T08:11:12,0\r\n2016-01-01T09:39:57,45\r\n2016-01-01T10:"
  },
  {
    "path": "examples/data/lightbulb-34.csv",
    "chars": 40126,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:39:27,45\r\n2016-01-01T09:04:42,0\r\n2016-01-01T09:15:29,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-35.csv",
    "chars": 39327,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:05:54,60\r\n2016-01-01T08:09:58,0\r\n2016-01-01T09:16:00,60\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-36.csv",
    "chars": 38763,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:39:41,45\r\n2016-01-01T08:42:03,0\r\n2016-01-01T09:03:52,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-37.csv",
    "chars": 2467672,
    "preview": "time,watts\r\n2016-01-01T00:00:00,0\r\n2016-01-01T00:01:00,0\r\n2016-01-01T00:02:00,0\r\n2016-01-01T00:03:00,0\r\n2016-01-01T00:04"
  },
  {
    "path": "examples/data/lightbulb-38.csv",
    "chars": 40596,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T07:38:25,45\r\n2016-01-01T07:55:38,0\r\n2016-01-01T08:48:02,45\r\n2016-01-01T09:"
  },
  {
    "path": "examples/data/lightbulb-39.csv",
    "chars": 38622,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T08:50:33,60\r\n2016-01-01T09:34:34,0\r\n2016-01-01T09:54:01,60\r\n2016-01-01T10:"
  },
  {
    "path": "examples/data/lightbulb-40.csv",
    "chars": 39609,
    "preview": "time,watts\r\n2016-01-01T06:31:41,0\r\n2016-01-01T09:39:59,45\r\n2016-01-01T10:09:32,0\r\n2016-01-01T10:22:59,45\r\n2016-01-01T10:"
  },
  {
    "path": "examples/event_analysis.py",
    "chars": 7503,
    "preview": "\"\"\"\nExample demonstrating how to use EventSeries for practical event analysis.\n\nThis example shows:\n1. Creating EventSer"
  },
  {
    "path": "examples/financial_analysis.py",
    "chars": 6971,
    "preview": "\"\"\"\r\nAdvanced example showing how to use traces for financial time series analysis.\r\n\r\nThis example demonstrates:\r\n1. Co"
  },
  {
    "path": "examples/helloworld.py",
    "chars": 2210,
    "preview": "import glob\nimport sys\nfrom datetime import datetime, timedelta\n\nimport traces\nfrom traces.utils import datetime_range\n\n"
  },
  {
    "path": "examples/iot_sensor_analysis.py",
    "chars": 10960,
    "preview": "\"\"\"\r\nAdvanced example showing how to use traces for IoT sensor data analysis.\r\n\r\nThis example demonstrates:\r\n1. Working "
  },
  {
    "path": "examples/stackystack.py",
    "chars": 2790,
    "preview": "import datetime\nimport random\n\nimport traces\n\n\ndef average(values):\n    sum_ = 0\n    n = 0\n    for i in values:\n        "
  },
  {
    "path": "examples/stackystack.py.bak",
    "chars": 2735,
    "preview": "import traces\nimport random\nimport datetime\nfrom infinity import inf\n\n\ndef average(values):\n    sum_ = 0\n    n = 0\n    f"
  },
  {
    "path": "examples/timing.py",
    "chars": 1801,
    "preview": "import collections\nimport functools\nimport sys\nimport time\n\nTIMING_RESULTS = collections.defaultdict(list)\n\n\nclass timer"
  },
  {
    "path": "experiments/bench_merge.py",
    "chars": 2729,
    "preview": "\"\"\"Benchmark iter_merge and merge performance.\n\nRun before and after optimization to compare.\n\nUsage:\n    poetry run pyt"
  },
  {
    "path": "experiments/bench_merge_strategies.py",
    "chars": 10100,
    "preview": "\"\"\"Benchmark three merge implementation strategies.\n\nThis script compares the performance characteristics of three\nappro"
  },
  {
    "path": "experiments/bench_sorted_dict.py",
    "chars": 9100,
    "preview": "\"\"\"Benchmark: traces built-in SortedDict vs sortedcontainers.SortedDict.\n\nCompares performance of TimeSeries operations "
  },
  {
    "path": "experiments/bench_tickets.py",
    "chars": 3196,
    "preview": "\"\"\"Compare two approaches for counting open tickets over time.\n\nApproach 1 (TimeSeries + merge(sum)):\n    One integer Ti"
  },
  {
    "path": "experiments/sorted_dict_replacement.py",
    "chars": 24333,
    "preview": "\"\"\"Prototype: dict + sorted list as a replacement for SortedDict in TimeSeries.\n\nThis file implements a DictTimeSeries c"
  },
  {
    "path": "mkdocs.yml",
    "chars": 1389,
    "preview": "site_name: traces\ndocs_dir: ./docs-md\nrepo_url: https://github.com/stringertheory/traces\nsite_url: https://stringertheor"
  },
  {
    "path": "poetry.toml",
    "chars": 32,
    "preview": "[virtualenvs]\nin-project = true\n"
  },
  {
    "path": "pyproject.toml",
    "chars": 3205,
    "preview": "[tool.poetry]\nname = \"traces\"\nversion  = \"0.7.0\"\ndescription = \"A Python library for unevenly-spaced time series analysi"
  },
  {
    "path": "tests/.coveragerc",
    "chars": 43,
    "preview": "# .coveragerc\n[report]\nshow_missing = True\n"
  },
  {
    "path": "tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/test_compact.py",
    "chars": 579,
    "preview": "import random\n\nimport traces\n\n\ndef test_compact():\n    # since this is random, do it a bunch of times\n    for _n_trial i"
  },
  {
    "path": "tests/test_distribution.py",
    "chars": 4534,
    "preview": "import datetime\n\nimport pytest\n\nfrom traces import Histogram, TimeSeries\n\n\ndef test_distribution():\n    start = datetime"
  },
  {
    "path": "tests/test_distribution_external.py",
    "chars": 691,
    "preview": "from pandas import Timestamp\n\nfrom traces import TimeSeries\n\n\ndef test_pandas_timestamp_range():\n    ts = TimeSeries(\n  "
  },
  {
    "path": "tests/test_docs.py",
    "chars": 1041,
    "preview": "from datetime import datetime\n\nimport traces\n\n\ndef test_quickstart():\n    time_series = traces.TimeSeries()\n    time_ser"
  },
  {
    "path": "tests/test_eventseries.py",
    "chars": 1148,
    "preview": "from traces import EventSeries\n\n\ndef test_init_data():\n    es = EventSeries([0, 0, 6, 8.7, 10])\n\n    assert es[0] == 0\n "
  },
  {
    "path": "tests/test_eventseries_external.py",
    "chars": 3390,
    "preview": "import pandas as pd\n\nfrom traces import EventSeries, TimeSeries\n\n\ndef test_cumsum():\n    # Test with basic timestamp dat"
  },
  {
    "path": "tests/test_histogram.py",
    "chars": 1543,
    "preview": "import traces\n\n\ndef test_normalize():\n    data = [15, 15, 20, 20, 20, 35, 35, 40, 40, 50, 50]\n    histogram = traces.His"
  },
  {
    "path": "tests/test_histogram_external.py",
    "chars": 3296,
    "preview": "import numpy\nimport pytest\nfrom scipy import stats\n\nimport traces\n\n\ndef test_quantiles():\n    data = [15, 15, 20, 20, 20"
  },
  {
    "path": "tests/test_improved_methods.py",
    "chars": 3611,
    "preview": "\"\"\"Tests for improved methods in TimeSeries.\"\"\"\r\n\r\nimport warnings\r\n\r\nfrom traces import TimeSeries\r\n\r\n\r\nclass TestImpro"
  },
  {
    "path": "tests/test_iterators.py",
    "chars": 8437,
    "preview": "import datetime\nimport pprint\nimport random\n\nimport pytest\n\nfrom traces import TimeSeries\n\n\ndef test_iterintervals():\n  "
  },
  {
    "path": "tests/test_json_io.py",
    "chars": 7951,
    "preview": "\"\"\"Tests for new JSON import/export functionality in TimeSeries.\"\"\"\r\n\r\nimport json\r\nimport os\r\nimport tempfile\r\nfrom dat"
  },
  {
    "path": "tests/test_methods.py",
    "chars": 10372,
    "preview": "import datetime\n\nimport pytest\n\nimport traces\n\nkey_list = [\n    datetime.datetime(2012, 1, 7),\n    datetime.datetime(201"
  },
  {
    "path": "tests/test_methods_external.py",
    "chars": 1138,
    "preview": "import numpy as np\nimport pandas as pd\n\nimport traces\n\n\ndef test_sample_pandas_compatibility():\n    ts = traces.TimeSeri"
  },
  {
    "path": "tests/test_missing.py",
    "chars": 2026,
    "preview": "import traces\n\n# @unittest.skip(\"not fully fleshed out yet\")\n\n\ndef test_missing():\n    \"\"\"example code for dealing with "
  },
  {
    "path": "tests/test_operations.py",
    "chars": 7009,
    "preview": "import datetime\n\nimport pytest\n\nfrom traces import TimeSeries\nfrom traces.decorators import ignorant\n\n\ndef test_scalar_o"
  },
  {
    "path": "tests/test_plot.py",
    "chars": 562,
    "preview": "import importlib\n\nimport pytest\n\nimport traces\n\nmatplotlib_importable = importlib.util.find_spec(\"matplotlib\")\n\n\ndef _ma"
  },
  {
    "path": "tests/test_plot_external.py",
    "chars": 626,
    "preview": "import pytest\n\nimport traces\n\n\n@pytest.mark.mpl_image_compare(\n    savefig_kwargs={\"bbox_inches\": \"tight\", \"dpi\": 300},\n"
  },
  {
    "path": "tests/test_something.py",
    "chars": 1398,
    "preview": "import contextlib\n\nimport traces\n\n\ndef test_compact():\n    # make a v. simple time series\n    ts = traces.TimeSeries()\n "
  },
  {
    "path": "tests/test_sorted_dict.py",
    "chars": 2784,
    "preview": "from traces.sorted_dict import SortedDict\n\n\ndef test_insert_maintains_sorted_order():\n    d = SortedDict()\n    d[3] = \"c"
  },
  {
    "path": "tests/test_traces.py",
    "chars": 6735,
    "preview": "import csv\nimport os\nimport pickle\nfrom datetime import datetime\n\nimport pytest\n\nfrom traces import TimeSeries\n\n\ndef tes"
  },
  {
    "path": "tests/test_traces_external.py",
    "chars": 5501,
    "preview": "import csv\nimport os\nfrom datetime import datetime, timedelta\n\nimport pandas as pd\nfrom dateutil.parser import parse as "
  },
  {
    "path": "tests/test_utils.py",
    "chars": 4493,
    "preview": "from datetime import date, datetime, timedelta\n\nimport pytest\n\nimport traces.utils as utils\nfrom traces.infinity import "
  },
  {
    "path": "tox.ini",
    "chars": 365,
    "preview": "[tox]\nskipsdist = true\nenvlist = py310, py311, py312, py313, py314\n\n[gh-actions]\npython =\n    3.10: py310\n    3.11: py31"
  },
  {
    "path": "traces/__init__.py",
    "chars": 305,
    "preview": "from . import decorators, operations\nfrom .eventseries import EventSeries\nfrom .histogram import Histogram\nfrom .infinit"
  },
  {
    "path": "traces/decorators.py",
    "chars": 526,
    "preview": "from functools import wraps\nfrom itertools import filterfalse\n\n\ndef _is_none(obj):\n    return obj is None\n\n\ndef ignorant"
  },
  {
    "path": "traces/eventseries.py",
    "chars": 8127,
    "preview": "\"\"\"EventSeries module for handling series of events occurring at specific times.\n\nThis module provides the EventSeries c"
  },
  {
    "path": "traces/histogram.py",
    "chars": 8008,
    "preview": "import math\n\nfrom .sorted_dict import SortedDict\n\n\nclass UnorderableElements(TypeError):\n    pass\n\n\nclass UnhashableType"
  },
  {
    "path": "traces/infinity.py",
    "chars": 4387,
    "preview": "\"\"\"This module is derived from the `infinity` package (at\nhttps://pypi.org/project/infinity/ or\nhttps://github.com/kvest"
  },
  {
    "path": "traces/operations.py",
    "chars": 195,
    "preview": "from .decorators import ignorant, strict\n\n\n@ignorant\ndef ignorant_sum(*args, **kwargs):\n    return sum(*args, **kwargs)\n"
  },
  {
    "path": "traces/plot.py",
    "chars": 3066,
    "preview": "\"\"\"For making quick plots for exploratory analysis.\"\"\"\n\nMIN_ASPECT_RATIO = 1 / 15\nMAX_ASPECT_RATIO = 1 / 3\nMAX_ASPECT_PO"
  },
  {
    "path": "traces/sorted_dict.py",
    "chars": 4015,
    "preview": "\"\"\"Lightweight sorted dictionary using dict + sorted list + bisect.\n\nThis is a very lightweight alternative to sortedcon"
  },
  {
    "path": "traces/timeseries.py",
    "chars": 59996,
    "preview": "\"\"\"A class for manipulating time series based on measurements at\nunevenly-spaced times, see:\n\nhttp://en.wikipedia.org/wi"
  },
  {
    "path": "traces/utils.py",
    "chars": 5632,
    "preview": "import contextlib\nimport datetime\nimport numbers\n\nfrom .infinity import inf\n\n\ndef duration_to_number(duration, units=\"se"
  }
]

About this extraction

This page contains the full source code of the datascopeanalytics/traces GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 129 files (15.8 MB), approximately 4.1M tokens, and a symbol index with 421 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!