# Path: cloudvolume/exceptions.py
# class OutOfBoundsError(ValueError):
#   """
#   Raised upon trying to obtain or assign to a bbox of a volume outside
#   of the volume's bounds
#   """


from typing import Union, Sequence, List, cast
from functools import reduce
from itertools import product
from PIL import Image
from tqdm import tqdm
from .exceptions import OutOfBoundsError
import decimal
import json
import math
import operator
import os
import random
import re 
import sys
import time
import types
import string 
import numpy as np
        x += stride_vec[0]
      x = start_vec[0]
      y += stride_vec[1] 
    y = start_vec[1]
    z += stride_vec[2]

def map2(fn, a, b):
  assert len(a) == len(b), "Vector lengths do not match: {} (len {}), {} (len {})".format(a[:3], len(a), b[:3], len(b))

  result = np.empty(len(a))

  for i in range(len(result)):
    result[i] = fn(a[i], b[i])

  if isinstance(a, Vec) or isinstance(b, Vec):
    return Vec(*result)

  return result

def max2(a, b):
  return map2(max, a, b).astype(a.dtype)

def min2(a, b):
  return map2(min, a, b).astype(a.dtype)

def clamp(val, low, high):
  return min(max(val, low), high)

def check_bounds(val, low, high):
  if val > high or val < low:

# Path: cloudvolume/exceptions.py
# class OutOfBoundsError(ValueError):
#   """
#   Raised upon trying to obtain or assign to a bbox of a volume outside
#   of the volume's bounds
#   """


# Path: cloudvolume/lib.py
from typing import Union, Sequence, List, cast
from functools import reduce
from itertools import product
from PIL import Image
from tqdm import tqdm
from .exceptions import OutOfBoundsError
import decimal
import json
import math
import operator
import os
import random
import re 
import sys
import time
import types
import string 
import numpy as np

        x += stride_vec[0]
      x = start_vec[0]
      y += stride_vec[1] 
    y = start_vec[1]
    z += stride_vec[2]

def map2(fn, a, b):
  assert len(a) == len(b), "Vector lengths do not match: {} (len {}), {} (len {})".format(a[:3], len(a), b[:3], len(b))

  result = np.empty(len(a))

  for i in range(len(result)):
    result[i] = fn(a[i], b[i])

  if isinstance(a, Vec) or isinstance(b, Vec):
    return Vec(*result)

  return result

def max2(a, b):
  return map2(max, a, b).astype(a.dtype)

def min2(a, b):
  return map2(min, a, b).astype(a.dtype)

def clamp(val, low, high):
  return min(max(val, low), high)

def check_bounds(val, low, high):
  if val > high or val < low:

    raise OutOfBoundsError('Value {} cannot be outside of inclusive range {} to {}'.format(val,low,high))