pax_global_header00006660000000000000000000000064133526731310014516gustar00rootroot0000000000000052 comment=999dcc21556265642f7249840e4c39b4b693aab0 unicorn-hat-hd-0.0.4/000077500000000000000000000000001335267313100143375ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/.gitattributes000066400000000000000000000002431335267313100172310ustar00rootroot00000000000000projects/unicornpaint/static/* linguist-vendored projects/unicornpaint/templates/* linguist-vendored packaging/* linguist-vendored sphinx/* linguist-documentation unicorn-hat-hd-0.0.4/.gitignore000066400000000000000000000005171335267313100163320ustar00rootroot00000000000000__pycache__/ sphinx/_build/ *.py[cod] *.swp *.upload dist/ sdist/ env/ build/ develop-eggs/ eggs/ *.egg-info/ .installed.cfg *.egg *.deb *.dsc *.build *.changes *.orig.* testing/ MANIFEST .idea pip-log.txt pip-delete-this-directory.txt library/debian/ packaging/*tar.xz .DS_Store sphinx.virtualenv .coverage .pytest_cache .tox .vscode unicorn-hat-hd-0.0.4/.travis.yml000066400000000000000000000006151335267313100164520ustar00rootroot00000000000000language: python sudo: false cache: pip git: submodules: true matrix: include: - python: "2.7" env: TOXENV=py27 - python: "3.5" env: TOXENV=py35 - python: "2.7" env: TOXENV=py27 install: - pip install --ignore-installed --upgrade setuptools pip tox coveralls script: - cd library - tox -vv after_success: if [ "$TOXENV" == "py35" ]; then coveralls; fi unicorn-hat-hd-0.0.4/LICENSE000066400000000000000000000020671335267313100153510ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2016 Pimoroni Ltd 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. unicorn-hat-hd-0.0.4/README.md000066400000000000000000000052241335267313100156210ustar00rootroot00000000000000![Unicorn HAT HD](unicorn-hat-hd-logo.png) http://shop.pimoroni.com/products/unicorn-hat-hd [![Build Status](https://travis-ci.com/pimoroni/unicorn-hat-hd.svg?branch=master)](https://travis-ci.com/pimoroni/unicorn-hat-hd) [![Coverage Status](https://coveralls.io/repos/github/pimoroni/unicorn-hat-hd/badge.svg?branch=master)](https://coveralls.io/github/pimoroni/unicorn-hat-hd?branch=master) [![PyPi Package](https://img.shields.io/pypi/v/unicornhathd.svg)](https://pypi.python.org/pypi/unicornhathd) [![Python Versions](https://img.shields.io/pypi/pyversions/unicornhathd.svg)](https://pypi.python.org/pypi/unicornhathd) ## Installing ### Full install (recommended): We've created an easy installation script that will install all pre-requisites and get your Unicorn HAT HD up and running with minimal efforts. To run it, fire up Terminal which you'll find in Menu -> Accessories -> Terminal on your Raspberry Pi desktop, as illustrated below: ![Finding the terminal](http://get.pimoroni.com/resources/github-repo-terminal.png) In the new terminal window type the command exactly as it appears below (check for typos) and follow the on-screen instructions: ```bash curl https://get.pimoroni.com/unicornhathd | bash ``` If you choose to download examples you'll find them in `/home/pi/Pimoroni/unicornhathd/`. To prototype and try out your code without having to deploy it onto a Raspberry Pi every time, you can use the [Unicorn HAT simulator](https://github.com/jayniz/unicorn-hat-sim) to run a mock Unicorn HAT on your computer. ### Manual install: SPI needs to be enabled to communicate with the Unicorn Hat HD. If the SPI on your Pi is not enabled or you are unsure if it is: ```bash sudo raspi-config nonint do_spi 0 sudo reboot ``` #### Library install for Python 3: ```bash sudo apt-get install python3-pip python3-dev python3-spidev sudo pip3 install unicornhathd ``` #### Library install for Python 2: ```bash sudo apt-get install python-pip python-dev python-spidev sudo pip install unicornhathd ``` ### Development: If you want to contribute, or like living on the edge of your seat by having the latest code, you should clone this repository, `cd` to the library directory, and run: ```bash sudo apt-get install python-dev python-setuptools sudo python3 setup.py install ``` (or `sudo python setup.py install` whichever your primary Python environment may be) In all cases you will have to enable the SPI bus. ## Documentation & Support * Guides and tutorials - https://learn.pimoroni.com/unicorn-hat-hd * Function reference - http://docs.pimoroni.com/unicornhathd/ * GPIO Pinout - http://pinout.xyz/pinout/unicorn_hat_hd * Get help - http://forums.pimoroni.com/c/support unicorn-hat-hd-0.0.4/examples/000077500000000000000000000000001335267313100161555ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/examples/camera.py000077500000000000000000000026631335267313100177710ustar00rootroot00000000000000#!/usr/bin/env python # Inspired by Ben Nuttall's Astro Cam example, # from: https://github.com/bennuttall/sense-hat-examples/blob/master/python/astro_cam.py # Written by Dave Jones: https://gist.github.com/waveform80/a2621da13b88c3d751e31a15e97695c2 # Tweaked for Unicorn HAT HD from signal import pause from sys import exit try: from picamera import PiCamera except ImportError: exit('This script requires the picamera module\nInstall with: sudo pip install picamera') try: from PIL import Image except ImportError: exit('This script requires the pillow module\nInstall with: sudo pip install pillow') import unicornhathd print("""Unicorn HAT HD: Raspberry Pi Camera Display Show a 16x16 feed from your Raspberry Pi camera! Press Ctrl+C to exit. """) class DisplayOutput(): def __init__(self): self.hat = unicornhathd self.hat.rotation(90) def write(self, buf): img = Image.frombytes('RGB', (64, 64), buf) img = img.resize((16, 16), Image.BILINEAR) for x in range(16): for y in range(16): r, g, b = img.getpixel((x, y)) self.hat.set_pixel(x, y, r, g, b) self.hat.show() with PiCamera() as camera: camera.resolution = (64, 64) camera.contrast = 50 camera.start_preview() output = DisplayOutput() camera.start_recording(output, 'rgb') try: pause() finally: camera.stop_recording() unicorn-hat-hd-0.0.4/examples/candle.py000077500000000000000000000047651335267313100177740ustar00rootroot00000000000000#!/usr/bin/env python import colorsys import math from random import randint import unicornhathd print("""Unicorn HAT HD: Candle This example simulates a flickering candle flame. Press Ctrl+C to exit! """) unicornhathd.rotation(0) width, height = unicornhathd.get_shape() # buffer to contain candle "heat" data candle = [0] * 256 # create a palette for mapping heat values onto colours palette = [0] * 256 for i in range(0, 256): h = i / 5.0 h /= 360.0 s = (1.0 / (math.sqrt(i / 50.0) + 0.01)) s = min(1.0, s) s = max(0.0, s) v = i / 200.0 if i < 60: v = v / 2 v = min(1.0, v) v = max(0.0, v) r, g, b = colorsys.hsv_to_rgb(h, s, v) palette[i] = (int(r * 255.0), int(g * 255.0), int(b * 255.0)) def set_pixel(b, x, y, v): b[y * 16 + x] = int(v) def get_pixel(b, x, y): # out of range sample lookup if x < 0 or y < 0 or x >= 16 or y >= 16: return 0 # subpixel sample lookup if isinstance(x, float) and x < 15: f = x - int(x) return (b[int(y) * 16 + int(x)] * (1.0 - f)) + (b[int(y) * 16 + int(x) + 1] * (f)) # fixed pixel sample lookup return b[int(y) * 16 + int(x)] step = 0 try: while True: # step for waving animation, adds some randomness step += randint(0, 15) # clone the current candle temp = candle[:] # seed new heat v = 500 set_pixel(candle, 6, 15, v) set_pixel(candle, 7, 15, v) set_pixel(candle, 8, 15, v) set_pixel(candle, 9, 15, v) set_pixel(candle, 6, 14, v) set_pixel(candle, 7, 14, v) set_pixel(candle, 8, 14, v) set_pixel(candle, 9, 14, v) # blur, wave, and shift up one step for x in range(0, 16): for y in range(0, 16): s = math.sin((y / 30.0) + (step / 10.0)) * ((16 - y) / 20.0) v = 0 for i in range(0, 3): for j in range(0, 3): # r = randint(0, 2) - 1 v += get_pixel(candle, x + i + s - 1, y + j) v /= 10 set_pixel(temp, x, y, v) candle = temp # copy candle into UHHD with palette for x in range(0, 16): for y in range(0, 16): o = (i * 3) + 1 r, g, b = palette[max(0, min(255, get_pixel(candle, x, y)))] unicornhathd.set_pixel(x, y, r, g, b) unicornhathd.show() except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/demo.py000077500000000000000000000107131335267313100174600ustar00rootroot00000000000000#!/usr/bin/env python import colorsys import math import time import unicornhathd print("""Unicorn HAT HD: demo.py This pixel shading demo transitions between 4 classic graphics demo effects. Press Ctrl+C to exit! """) unicornhathd.rotation(0) u_width, u_height = unicornhathd.get_shape() # Generate a lookup table for 8bit hue to RGB conversion hue_to_rgb = [] for i in range(0, 255): hue_to_rgb.append(colorsys.hsv_to_rgb(i / 255.0, 1, 1)) def gradient(x, y, step): g = x * 16 b = y * 16 r = 255 - (x * 16) return (r, g, b) # twisty swirly goodness def swirl(x, y, step): x -= (u_width / 2) y -= (u_height / 2) dist = math.sqrt(pow(x, 2) + pow(y, 2)) / 2.0 angle = (step / 10.0) + (dist * 1.5) s = math.sin(angle) c = math.cos(angle) xs = x * c - y * s ys = x * s + y * c r = abs(xs + ys) r = r * 12.0 r -= 20 return (r, r + (s * 130), r + (c * 130)) # roto-zooming checker board def checker(x, y, step): x -= (u_width / 2) y -= (u_height / 2) angle = (step / 10.0) s = math.sin(angle) c = math.cos(angle) xs = x * c - y * s ys = x * s + y * c xs -= math.sin(step / 200.0) * 40.0 ys -= math.cos(step / 200.0) * 40.0 scale = step % 20 scale /= 20 scale = (math.sin(step / 50.0) / 8.0) + 0.25 xs *= scale ys *= scale xo = abs(xs) - int(abs(xs)) yo = abs(ys) - int(abs(ys)) v = 0 if (math.floor(xs) + math.floor(ys)) % 2 else 1 if xo > .1 and yo > .1 else .5 r, g, b = hue_to_rgb[step % 255] return (r * (v * 255), g * (v * 255), b * (v * 255)) # weeee waaaah def blues_and_twos(x, y, step): x -= (u_width / 2) y -= (u_height / 2) scale = math.sin(step / 6.0) / 1.5 r = math.sin((x * scale) / 1.0) + math.cos((y * scale) / 1.0) b = math.sin(x * scale / 2.0) + math.cos(y * scale / 2.0) g = r - .8 g = 0 if g < 0 else g b -= r b /= 1.4 return (r * 255, (b + g) * 255, g * 255) # rainbow search spotlights def rainbow_search(x, y, step): xs = math.sin((step) / 100.0) * 20.0 ys = math.cos((step) / 100.0) * 20.0 scale = ((math.sin(step / 60.0) + 1.0) / 5.0) + 0.2 r = math.sin((x + xs) * scale) + math.cos((y + xs) * scale) g = math.sin((x + xs) * scale) + math.cos((y + ys) * scale) b = math.sin((x + ys) * scale) + math.cos((y + ys) * scale) return (r * 255, g * 255, b * 255) # zoom tunnel def tunnel(x, y, step): speed = step / 100.0 x -= (u_width / 2) y -= (u_height / 2) xo = math.sin(step / 27.0) * 2 yo = math.cos(step / 18.0) * 2 x += xo y += yo if y == 0: if x < 0: angle = -(math.pi / 2) else: angle = (math.pi / 2) else: angle = math.atan(x / y) if y > 0: angle += math.pi angle /= 2 * math.pi # convert angle to 0...1 range hyp = math.sqrt(math.pow(x, 2) + math.pow(y, 2)) shade = hyp / 2.1 shade = 1 if shade > 1 else shade angle += speed depth = speed + (hyp / 10) col1 = hue_to_rgb[step % 255] col1 = (col1[0] * 0.8, col1[1] * 0.8, col1[2] * 0.8) col2 = hue_to_rgb[step % 255] col2 = (col2[0] * 0.3, col2[1] * 0.3, col2[2] * 0.3) col = col1 if int(abs(angle * 6.0)) % 2 == 0 else col2 td = .3 if int(abs(depth * 3.0)) % 2 == 0 else 0 col = (col[0] + td, col[1] + td, col[2] + td) col = (col[0] * shade, col[1] * shade, col[2] * shade) return (col[0] * 255, col[1] * 255, col[2] * 255) def current_milli_time(): return int(round(time.time() * 1000)) effects = [gradient, tunnel, rainbow_search, checker, swirl] step = 0 try: while True: for i in range(100): start = current_milli_time() for y in range(u_height): for x in range(u_width): r, g, b = effects[0](x, y, step) if i > 75: r2, g2, b2 = effects[-1](x, y, step) ratio = (100.00 - i) / 25.0 r = r * ratio + r2 * (1.0 - ratio) g = g * ratio + g2 * (1.0 - ratio) b = b * ratio + b2 * (1.0 - ratio) r = int(max(0, min(255, r))) g = int(max(0, min(255, g))) b = int(max(0, min(255, b))) unicornhathd.set_pixel(x, y, r, g, b) step += 2 unicornhathd.show() effect = effects.pop() effects.insert(0, effect) except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/forest-fire.py000077500000000000000000000052221335267313100207600ustar00rootroot00000000000000#!/usr/bin/env python import random from sys import exit try: import numpy except ImportError: exit('This script requires the numpy module\nInstall with: sudo pip install numpy') import unicornhathd print("""Unicorn HAT HD: Forest Fire This example simulates a forest fire. Press Ctrl+C to exit! """) scale = 3 unicornhathd.rotation(0) width, height = unicornhathd.get_shape() forest_width = width * scale forest_height = height * scale hood_size = 3 avg_size = scale def get_neighbours(x, y, z): return [(x2, y2) for x2 in range(x - (z - 1), x + z) for y2 in range(y - (z - 1), y + z) if (-1 < x < forest_width and -1 < y < forest_height and (x != x2 or y != y2) and (0 <= x2 < forest_width) and (0 <= y2 < forest_height))] initial_trees = 0.55 p = 0.01 f = 0.0005 tree = [0, 255, 0] burning = [255, 0, 0] space = [0, 0, 0] def initialise(): forest = [[tree if random.random() <= initial_trees else space for x in range(forest_width)] for y in range(forest_height)] return forest def update_forest(forest): new_forest = [[space for x in range(forest_width)] for y in range(forest_height)] for x in range(forest_width): for y in range(forest_height): if forest[x][y] == burning: new_forest[x][y] = space elif forest[x][y] == space: new_forest[x][y] = tree if random.random() <= p else space elif forest[x][y] == tree: neighbours = get_neighbours(x, y, hood_size) new_forest[x][y] = (burning if any([forest[n[0]][n[1]] == burning for n in neighbours]) or random.random() <= f else tree) return new_forest def average_forest(forest): avg_forest = [[space for x in range(width)] for y in range(height)] for i, x in enumerate(range(1, forest_width, scale)): for j, y in enumerate(range(1, forest_height, scale)): neighbours = get_neighbours(x, y, avg_size) red = int(numpy.mean([forest[n[0]][n[1]][0] for n in neighbours])) green = int(numpy.mean([forest[n[0]][n[1]][1] for n in neighbours])) blue = int(numpy.mean([forest[n[0]][n[1]][2] for n in neighbours])) avg_forest[i][j] = [red, green, blue] return avg_forest def show_forest(forest): avg_forest = average_forest(forest) for x in range(width): for y in range(height): r, g, b = avg_forest[x][y] unicornhathd.set_pixel(x, y, int(r), int(g), int(b)) unicornhathd.show() def main(): forest = initialise() while True: show_forest(forest) forest = update_forest(forest) try: main() except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/game-of-life.py000077500000000000000000000045371335267313100207730ustar00rootroot00000000000000#!/usr/bin/env python import random import time import unicornhathd print("""Unicorn HAT HD: Game Of Life Runs Conway's Game Of Life on your Unicorn HAT, this starts with a random spread of life, so results may vary! """) try: xrange except NameError: xrange = range unicornhathd.rotation(0) unicornhathd.brightness(0.5) width, height = unicornhathd.get_shape() size = width * height class GameOfLife: def __init__(self): self.board = [int(7 * random.getrandbits(1)) for _ in xrange(size)] self.color = [[154, 154, 174], [0, 0, 255], [0, 0, 200], [0, 0, 160], [0, 0, 140], [0, 0, 90], [0, 0, 60], [0, 0, 0]] def value(self, x, y): index = ((x % width) * height) + (y % height) return self.board[index] def neighbors(self, x, y): sum = 0 for i in xrange(3): for j in xrange(3): if i == 1 and j == 1: continue if self.value(x + i - 1, y + j - 1) == 0: sum = sum + 1 return sum def next_generation(self): new_board = [False] * size for i in xrange(width): for j in xrange(height): neigh = self.neighbors(i, j) lvl = self.value(i, j) if lvl == 0: if neigh < 2: new_board[i * height + j] = min(7, lvl + 1) elif 2 <= neigh <= 3: new_board[i * height + j] = 0 else: new_board[i * height + j] = min(7, lvl + 1) else: if neigh == 3: new_board[i * height + j] = 0 else: new_board[i * height + j] = min(7, lvl + 1) self.board = new_board def all_dead(self): for i in xrange(size): if self.board[i] != 7: return False return True def show_board(self): for i in xrange(width): for j in xrange(height): rgb = self.color[self.value(i, j)] unicornhathd.set_pixel(i, j, rgb[0], rgb[1], rgb[2]) unicornhathd.show() life = GameOfLife() try: while not life.all_dead(): life.next_generation() life.show_board() time.sleep(0.05) except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/graph.py000077500000000000000000000030071335267313100176330ustar00rootroot00000000000000#!/usr/bin/env python import math import time # import random # Required for random values # from colorsys import hsv_to_rgb # required for trippy bar colours import unicornhathd print("""Unicorn HAT HD: graph.py This graph demo shows how you might display a range of values on UHHD. Press Ctrl+C to exit! """) unicornhathd.rotation(0) unicornhathd.brightness(0.6) u_width, u_height = unicornhathd.get_shape() bar_speed = 16 bar_width = 2 bar_colour = [64, 0, 128] # Create our array of values to display on the chart # These should always be scaled to the range 0.0 to 1.0 # Sine wave! values = [(math.sin((x / 16.0) * math.pi) + 1.0) / 2.0 for x in range(32)] # Random values # values = [random.randint(0,127) / 127.0 for _ in range(32)] try: while True: for x in range(u_width / bar_width): value = (values[x] * u_height) # Scale the graph range 0.0 to 1.0 to the display height # Trippy bar colours! # bar_colour = [int(c * 255) for c in hsv_to_rgb(values[x] / 2, 1.0, 1.0)] for y in range(u_height): brightness = min(1.0, value - y) r, g, b = [int(c * brightness) for c in bar_colour] for z in range(bar_width): unicornhathd.set_pixel((x * bar_width) + z, y, r, g, b) unicornhathd.show() values.append(values.pop(0)) # Move the first value to the end of the array time.sleep(1.0 / bar_speed) except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/line.py000077500000000000000000000015401335267313100174610ustar00rootroot00000000000000#!/usr/bin/env python import time import unicornhathd while True: for rotation in [0, 90, 180, 270]: print('Showing lines at rotation: {}'.format(rotation)) unicornhathd.clear() unicornhathd.rotation(rotation) unicornhathd.set_pixel(0, 0, 64, 64, 64) unicornhathd.show() time.sleep(0.5) for x in range(1, 16): unicornhathd.set_pixel(x, 0, 255, 0, 0) unicornhathd.show() time.sleep(0.5 / 16) time.sleep(0.5) for y in range(1, 16): unicornhathd.set_pixel(0, y, 0, 0, 255) unicornhathd.show() time.sleep(0.5 / 16) time.sleep(0.5) for b in range(1, 16): unicornhathd.set_pixel(b, b, 0, 255, 0) unicornhathd.show() time.sleep(0.5 / 16) time.sleep(0.5) unicorn-hat-hd-0.0.4/examples/lofi.png000066400000000000000000000034301335267313100176140ustar00rootroot00000000000000PNG  IHDR "p%,tEXtCreation TimeSun 29 Nov 2009 17:56:31 -0000tIME  pHYsiTSgAMA aoIDATxZKEYI *9!/*"$h.(]]APыqoQ1]\%K`vTs@ zTw =GWuwĎ,Qp ĀY~jjDϏk/i?pJ?v`~ٖW{S%s`N| ouSXgv&i^.sȳix6|,/P Cm,jbM7)NtݔR],/A𜮒ZVc6-Vodw5Ԉ~ͥ//yTs&ybXǿk:f7L| _~(矤uߛMLgrrdy%-++'sM3#e\{YA}vvtA>MBKN Z4Myg֭{σH'@\ۧ1K0>r$rL$&1KpJ P4@mh/M>iLK_;z8ퟃ3 2$6l(M{->zeofC#G,f[D'3 sOsoSX䞧7[xPÏӏʙ][멜Mޱ$+c{)-n;q&sd9IZcчy $  ,04҄ $g~Okk=|#+ -~ e\N`>EK}0ڗL^-%&0}LmG'0W( /=ܕ~S`2}Ouy9;98Gk[S+@KKcp -,^-^6>ɰO c[1iOK iP;{戭6hd>Kpn};/plŠ&g| 1PEp& !6kg/ $3NBa 0la~[KG,8f5t"UniwCiKCJ!"g|X/6~Z}||m~%Yf~ƙ5` (@;oC0%Nn ZQK݂r-N!%'DCg5h+4-] }=?`Ӈ.#QFVX . X.|arƸ駉;I@xGy 9S`۷F],~P_F&>@h ߚ1=-kCFsgO; +NCujBir1Yz[h?`2*N 7drS[B6zD %l+>@wK}L/"xQ3jmo-8vKMqHO?Tk; ;|IENDB`unicorn-hat-hd-0.0.4/examples/matrixhd.py000077500000000000000000000025271335267313100203600ustar00rootroot00000000000000#!/usr/bin/env python # # Ported from Pimoroni Unicorn Hat example https://github.com/pimoroni/unicorn-hat/blob/master/examples/hat/matrix.py # to unicornhat hd by aburgess@gmail.com (https://github.com/Mutiny-Games) # import time from random import randint import unicornhathd as unicorn print("""Matrix Follow the white rabbit... """) unicorn.rotation(270) wrd_rgb = [ [154, 173, 154], [0, 255, 0], [0, 235, 0], [0, 220, 0], [0, 185, 0], [0, 165, 0], [0, 128, 0], [0, 0, 0], [154, 173, 154], [0, 145, 0], [0, 125, 0], [0, 100, 0], [0, 80, 0], [0, 60, 0], [0, 40, 0], [0, 0, 0] ] clock = 0 blue_pilled_population = [[randint(0, 15), 15]] try: while True: for person in blue_pilled_population: y = person[1] for rgb in wrd_rgb: if (y <= 15) and (y >= 0): unicorn.set_pixel(person[0], y, rgb[0], rgb[1], rgb[2]) y += 1 person[1] -= 1 unicorn.show() time.sleep(0.1) clock += 1 if clock % 5 == 0: blue_pilled_population.append([randint(0, 15), 15]) if clock % 7 == 0: blue_pilled_population.append([randint(0, 15), 15]) while len(blue_pilled_population) > 100: blue_pilled_population.pop(0) except KeyboardInterrupt: pass unicorn.clear() unicorn.show() unicorn-hat-hd-0.0.4/examples/rainbow-text.py000077500000000000000000000121411335267313100211540ustar00rootroot00000000000000#!/usr/bin/env python import colorsys import time from sys import exit try: from PIL import Image, ImageDraw, ImageFont except ImportError: exit('This script requires the pillow module\nInstall with: sudo pip install pillow') import unicornhathd print("""Unicorn HAT HD: Text This example shows how to draw, display and scroll text in a regular TrueType font on Unicorn HAT HD. It uses the Python Pillow/PIL image library, and all other drawing functions are available. See: http://pillow.readthedocs.io/en/3.1.x/reference/ """) # ========== Change the text you want to display, and font, here ================ TEXT = 'Hello World! How are you today? This is a real font!' FONT = ('/usr/share/fonts/truetype/freefont/FreeSansBold.ttf', 12) # Use `fc-list` to show a list of installed fonts on your system, # or `ls /usr/share/fonts/` and explore. # sudo apt install fonts-droid # FONT = ('/usr/share/fonts/truetype/droid/DroidSans.ttf', 12) # sudo apt install fonts-roboto # FONT = ('/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf', 10) # ================ Now, let's draw some amazing rainbowy text! =================== # Get the width/height of Unicorn HAT HD. # These will normally be 16x16 but it's good practise not to hard-code such numbers, # just in case you want to try and hack together a bigger display later. width, height = unicornhathd.get_shape() unicornhathd.rotation(0) unicornhathd.brightness(0.5) # We want to draw our text 1 pixel in, and 2 pixels down from the top left corner text_x = 1 text_y = 2 # Grab our font file and size as defined at the top of the script font_file, font_size = FONT # Load the font using PIL's ImageFont font = ImageFont.truetype(font_file, font_size) # Ask the loaded font how big our text will be text_width, text_height = font.getsize(TEXT) # Make sure we accommodate enough width to account for our text_x left offset text_width += width + text_x # Now let's create a blank canvas wide enough to accomodate our text image = Image.new('RGB', (text_width, max(height, text_height)), (0, 0, 0)) # To draw on our image, we must use PIL's ImageDraw draw = ImageDraw.Draw(image) # And now we can draw text at our desited (text_x, text_y) offset, using our loaded font draw.text((text_x, text_y), TEXT, fill=(255, 255, 255), font=font) # To give an appearance of scrolling text, we move a 16x16 "window" across the image we generated above # The value "scroll" denotes how far this window is from the left of the image. # Since the window is "width" pixels wide (16 for UHHD) and we don't want it to run off the end of the, # image, we subtract "width". for scroll in range(text_width - width): for x in range(width): # Figure out what hue value we want at this point. # "x" is the position of the pixel on Unicorn HAT HD from 0 to 15 # "scroll" is how far offset from the left of our text image we are # We want the text to be a complete cycle around the hue in the HSV colour space # so we divide the pixel's position (x + scroll) by the total width of the text # If this pixel were half way through the text, it would result in the number 0.5 (180 degrees) hue = (x + scroll) / float(text_width) # Now we need to convert our "hue" value into r,g,b since that's what colour space our # image is in, and also what Unicorn HAT HD understands. # This list comprehension is just a tidy way of converting the range 0.0 to 1.0 # that hsv_to_rgb returns into integers in the range 0-255. # hsv_to_rgb returns a tuple of (r, g, b) br, bg, bb = [int(n * 255) for n in colorsys.hsv_to_rgb(hue, 1.0, 1.0)] # Since our rainbow runs from left to right along the x axis, we can calculate it once # for every vertical line on the display, and then re-use that value 16 times below: for y in range(height): # Get the r, g, b colour triplet from pixel x,y of our text image # Our text is white on a black background, so these will all be shades of black/grey/white # ie 255,255,255 or 0,0,0 or 128,128,128 pixel = image.getpixel((x + scroll, y)) # Now we want to turn the colour of our text - shades of grey remember - into a mask for our rainbow. # We do this by dividing it by 255, which converts it to the range 0.0 to 1.0 r, g, b = [float(n / 255.0) for n in pixel] # We can now use our 0.0 to 1.0 range to scale our three colour values, controlling the amount # of rainbow that gets blended in. # 0.0 would blend no rainbow # 1.0 would blend 100% rainbow # and anything in between would copy the anti-aliased edges from our text r = int(br * r) g = int(bg * g) b = int(bb * b) # Finally we colour in our finished pixel on Unicorn HAT HD unicornhathd.set_pixel(width - 1 - x, y, r, g, b) # Finally, for each step in our scroll, we show the result on Unicorn HAT HD unicornhathd.show() # And sleep for a little bit, so it doesn't scroll too quickly! time.sleep(0.02) unicornhathd.off() unicorn-hat-hd-0.0.4/examples/rainbow.py000077500000000000000000000016111335267313100201720ustar00rootroot00000000000000#!/usr/bin/env python import colorsys import math import time import unicornhathd print("""Unicorn HAT HD: Rainbow OMG MY EYES. Press Ctrl+C to exit! """) unicornhathd.rotation(0) step = 0 try: while True: step += 1 for x in range(0, 16): for y in range(0, 16): dx = 7 dy = 7 dx = (math.sin(step / 20.0) * 15.0) + 7.0 dy = (math.cos(step / 15.0) * 15.0) + 7.0 sc = (math.cos(step / 10.0) * 10.0) + 16.0 h = math.sqrt(math.pow(x - dx, 2) + math.pow(y - dy, 2)) / sc r, g, b = colorsys.hsv_to_rgb(h, 1, 1) r *= 255.0 g *= 255.0 b *= 255.0 unicornhathd.set_pixel(x, y, r, g, b) unicornhathd.show() time.sleep(1.0 / 60) except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/raspicam.py000077500000000000000000000016331335267313100203340ustar00rootroot00000000000000#!/usr/bin/env python # This is a modified version of Ben Nuttall's Astro Cam example, # from: https://github.com/bennuttall/sense-hat-examples/blob/master/python/astro_cam.py try: from picamera import PiCamera from picamera.array import PiRGBArray except ImportError: exit('This script requires the picamera module\nInstall with: sudo pip install picamera') import unicornhathd print("""Unicorn HAT HD: Raspberry Pi Camera Display Show a 16x16 feed from your Raspberry Pi camera! """) while True: with PiCamera() as camera: camera.resolution = (32, 32) with PiRGBArray(camera, size=(16, 16)) as stream: camera.capture(stream, format='rgb', resize=(16, 16)) image = stream.array for y, row in enumerate(image): for x, pixel in enumerate(row): r, g, b = pixel unicornhathd.set_pixel(x, y, r, g, b) unicornhathd.show() unicorn-hat-hd-0.0.4/examples/setup.cfg000066400000000000000000000002011335267313100177670ustar00rootroot00000000000000[flake8] exclude = test.py .tox, .eggs, .git, __pycache__, build, dist ignore = E501 D100 D101 D102 D103 D107 unicorn-hat-hd-0.0.4/examples/show-png.py000077500000000000000000000025471335267313100203040ustar00rootroot00000000000000#!/usr/bin/env python import time from sys import exit try: from PIL import Image except ImportError: exit('This script requires the pillow module\nInstall with: sudo pip install pillow') import unicornhathd print("""Unicorn HAT HD: Show a PNG image! This basic example shows use of the Python Pillow library: The tiny 16x16 bosses in lofi.png are from Oddball: http://forums.tigsource.com/index.php?topic=8834.0 Licensed under Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Press Ctrl+C to exit! """) unicornhathd.rotation(90) unicornhathd.brightness(0.5) width, height = unicornhathd.get_shape() img = Image.open('lofi.png') try: while True: for o_x in range(int(img.size[0] / width)): for o_y in range(int(img.size[1] / height)): valid = False for x in range(width): for y in range(height): pixel = img.getpixel(((o_x * width) + y, (o_y * height) + x)) r, g, b = int(pixel[0]), int(pixel[1]), int(pixel[2]) if r or g or b: valid = True unicornhathd.set_pixel(x, y, r, g, b) if valid: unicornhathd.show() time.sleep(0.5) except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/snake.py000077500000000000000000000122121335267313100176310ustar00rootroot00000000000000#!/usr/bin/env python import curses import random import time import unicornhathd CONTROLS = { ord('w'): 'up', ord('s'): 'down', ord('a'): 'left', ord('d'): 'right', curses.KEY_UP: 'up', curses.KEY_DOWN: 'down', curses.KEY_LEFT: 'left', curses.KEY_RIGHT: 'right' } class Snake: def __init__(self, canvas, x=5, y=5): self.position = (x, y) self.velocity = (1, 0) self.length = 1 self.score = 0 self.tail = [] self.colour_head = (128, 0, 255) self.colour_tail = (32, 0, 64) self.canvas = canvas self.eaten = [] self.grow_speed = 1 def poo(self): self.eaten = [] self.tail = [] self.length = 1 self.grow_speed += 1 def shrink(self): if self.length > 1: self.length -= 1 self.tail = self.tail[-self.length:] if len(self.eaten) > 0: self.eaten.pop(0) def get_colour(self, x, y): if (x, y) == self.position: return self.colour_head elif (x, y) in self.tail: return self.colour_tail def draw(self): for position in [self.position] + self.tail: x, y = position r, g, b = self.get_colour(x, y) self.canvas.set_pixel(x, y, r, g, b) for idx, colour in enumerate(self.eaten): r, g, b = colour self.canvas.set_pixel(idx, 14, r >> 1, g >> 1, b >> 1) def num_eaten(self): return len(self.eaten) def update(self, apples, direction=''): x, y = self.position if direction == 'left' and self.velocity != (1, 0): self.velocity = (-1, 0) if direction == 'right' and self.velocity != (-1, 0): self.velocity = (1, 0) if direction == 'up' and self.velocity != (0, -1): self.velocity = (0, 1) if direction == 'down' and self.velocity != (0, 1): self.velocity = (0, -1) v_x, v_y = self.velocity x += v_x y += v_y c_x, c_y = self.canvas.get_shape() c_y -= 3 # 3 pixels along the top for score x %= c_x y %= c_y if (x, y) in self.tail: return False self.tail.append(self.position) self.tail = self.tail[-self.length:] self.position = (x, y) for apple in apples: if apple.position == self.position: score = apple.eat() if score > 0: self.score += score self.length += self.grow_speed self.eaten.append(apple.get_colour()) return True class Apple: colours = [(128, 0, 0), (0, 128, 0), (96, 96, 0)] def __init__(self, canvas): self.canvas = canvas self.reset() def get_colour(self): return self.colours[self.score] def reset(self): c_x, c_y = self.canvas.get_shape() c_y -= 3 self.position = (random.randint(0, c_x - 1), random.randint(0, c_y - 1)) self.score = random.randint(0, len(self.colours) - 1) self.eaten = False def eat(self): if self.eaten: return 0 self.eaten = True return self.score + 1 def update(self): pass # What's an apple 'gon do? def draw(self): if self.eaten: return x, y = self.position r, g, b = self.get_colour() self.canvas.set_pixel(x, y, r, g, b) def main(stdscr): stdscr.nodelay(1) stdscr.addstr(2, 5, 'Unicorn HAT HD: Snake') stdscr.addstr(4, 5, 'w = UP, s = DOWN, a = LEFT, d = RIGHT') stdscr.addstr(6, 5, 'Press Ctrl+C to exit!') width, height = unicornhathd.get_shape() step = 0 running = True num_apples = 16 snake = Snake(unicornhathd, 13, 5) apples = [Apple(unicornhathd) for x in range(num_apples)] hit = False try: while running: unicornhathd.clear() for x in range(16): for y in range(3): unicornhathd.set_pixel(x, 15 - y, 10, 10, 10) if hit: if snake.length == 1: hit = False for apple in apples: apple.reset() continue snake.shrink() snake.draw() else: for apple in apples: apple.update() apple.draw() dir = '' key = 0 while key != -1: key = stdscr.getch() if key in CONTROLS: dir = CONTROLS[key] hit = not snake.update(apples, dir) if snake.num_eaten() == num_apples: snake.poo() for apple in apples: apple.reset() apple.draw() snake.draw() unicornhathd.show() step += 1 time.sleep(0.1) print('You scored: {}'.format(snake.score)) except KeyboardInterrupt: pass if __name__ == '__main__': curses.wrapper(main) unicorn-hat-hd-0.0.4/examples/stars.py000077500000000000000000000016741335267313100176760ustar00rootroot00000000000000#!/usr/bin/env python import random import unicornhathd print("""Unicorn HAT HD: Stars This example simulates a wooshing star field. Press Ctrl+C to exit! """) star_count = 25 star_speed = 0.05 stars = [] for i in range(0, star_count): stars.append((random.uniform(4, 11), random.uniform(4, 11), 0)) try: while True: unicornhathd.clear() for i in range(0, star_count): stars[i] = ( stars[i][0] + ((stars[i][0] - 8.1) * star_speed), stars[i][1] + ((stars[i][1] - 8.1) * star_speed), stars[i][2] + star_speed * 50) if stars[i][0] < 0 or stars[i][1] < 0 or stars[i][0] > 16 or stars[i][1] > 16: stars[i] = (random.uniform(4, 11), random.uniform(4, 11), 0) v = stars[i][2] unicornhathd.set_pixel(stars[i][0], stars[i][1], v, v, v) unicornhathd.show() except KeyboardInterrupt: unicornhathd.off() unicorn-hat-hd-0.0.4/examples/test.py000077500000000000000000000006771335267313100175230ustar00rootroot00000000000000#!/usr/bin/env python import time import unicornhathd unicornhathd.clear() unicornhathd.set_all(10, 0, 10) unicornhathd._buf = unicornhathd.numpy.random.randint(low=0,high=255,size=(16,16,3)) frame = 0 t_start = time.time() try: while True: unicornhathd.show() unicornhathd.rotation(frame) frame += 1 except KeyboardInterrupt: print("FPS: {}".format(frame / (time.time() - t_start))) unicornhathd.off() unicorn-hat-hd-0.0.4/examples/text.py000077500000000000000000000044521335267313100175230ustar00rootroot00000000000000#!/usr/bin/env python import colorsys import time from sys import exit try: from PIL import Image, ImageDraw, ImageFont except ImportError: exit('This script requires the pillow module\nInstall with: sudo pip install pillow') import unicornhathd print("""Unicorn HAT HD: Text This example shows how to draw, display and scroll text in a regular TrueType font on Unicorn HAT HD. It uses the Python Pillow/PIL image library, and all other drawing functions are available. See: http://pillow.readthedocs.io/en/3.1.x/reference/ """) lines = ["In the old #BILGETANK we'll keep you in the know", "In the old #BILGETANK we'll fix your techie woes", "And we'll make things", "And we'll break things", "'til we're altogether aching", "Then we'll grab a cup of grog down in the old #BILGETANK"] colours = [tuple([int(n * 255) for n in colorsys.hsv_to_rgb(x / float(len(lines)), 1.0, 1.0)]) for x in range(len(lines))] # Use `fc-list` to show a list of installed fonts on your system, # or `ls /usr/share/fonts/` and explore. FONT = ('/usr/share/fonts/truetype/freefont/FreeSansBold.ttf', 12) # sudo apt install fonts-droid # FONT = ('/usr/share/fonts/truetype/droid/DroidSans.ttf', 12) # sudo apt install fonts-roboto # FONT = ('/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf', 10) unicornhathd.rotation(0) unicornhathd.brightness(1.0) width, height = unicornhathd.get_shape() text_x = width text_y = 2 font_file, font_size = FONT font = ImageFont.truetype(font_file, font_size) text_width, text_height = width, 0 for line in lines: w, h = font.getsize(line) text_width += w + width text_height = max(text_height, h) text_width += width + text_x + 1 image = Image.new('RGB', (text_width, max(16, text_height)), (0, 0, 0)) draw = ImageDraw.Draw(image) offset_left = 0 for index, line in enumerate(lines): draw.text((text_x + offset_left, text_y), line, colours[index], font=font) offset_left += font.getsize(line)[0] + width for scroll in range(text_width - width): for x in range(width): for y in range(height): pixel = image.getpixel((x + scroll, y)) r, g, b = [int(n) for n in pixel] unicornhathd.set_pixel(width - 1 - x, y, r, g, b) unicornhathd.show() time.sleep(0.01) unicornhathd.off() unicorn-hat-hd-0.0.4/examples/weather-icons/000077500000000000000000000000001335267313100207255ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/examples/weather-icons/LICENSE000066400000000000000000000021001335267313100217230ustar00rootroot00000000000000The MIT License (MIT) Icons Copyright (c) 2016 LoveBootCaptain 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. unicorn-hat-hd-0.0.4/examples/weather-icons/README.md000066400000000000000000000077611335267313100222170ustar00rootroot00000000000000# animated weather icons for the unicorn-hat-hd handmade weather animations for unicorn-hat-hd made by pimoroni. each hd animation is made of 32 handmade mini pictures, combined to a sprite. draw_animation(image) is same as in the 'show-png' example but put into a tiny little function. put in your image object and you're done. [pimoroni's show-png example](https://github.com/pimoroni/unicorn-hat-hd/blob/master/examples/show-png.py "pimoroni's show-png example") the draw_animation() function will loop through all images in the sprite and it will look like a tiny animation. Awesome !! you can change the 'fps' with changing the 'cycle_time' variable (0.25 is very smooth). loop() finally loops through all png images in a folder (you might guessed it) so you can see all possibilities. Usage: ```python weather-icons.py options``` options: - loop - image-file.png example: ```weather-icons.py loop``` ```weather-icons.py clear-day.png``` ## new unicorn-hat-hd animations 16x16 | | unicornhat hd | | |:---------------------------:|:---------------------------------------:|:-------------------------------------------:| | fog | partly-cloudy-day | partly-cloudy-night | | ![fog][fog] | ![partly-cloudy-day][partly-cloudy-day] | ![partly-cloudy-night][partly-cloudy-night] | | clear-night | clear-day | cloudy | | ![clear-night][clear-night] | ![clear-day][clear-day] | ![cloudy][cloudy] | | rain | snow | windy | | ![rain][rain] | ![snow][snow] | ![windy][windy] | | error | raspberry | pimoroni pirate | | ![error][error] | ![raspberry][raspberry] | ![pimoroni_pirate][pimoroni_pirate] | [clear-day]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/clear-day.gif "clear-day" [clear-night]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/clear-night.gif "clear-night" [cloudy]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/cloudy.gif "cloudy" [fog]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/fog.gif "cloudy" [partly-cloudy-day]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/partly-cloudy-day.gif "partly-cloudy-day" [partly-cloudy-night]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/partly-cloudy-night.gif "partly-cloudy-night" [rain]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/rain.gif "rain" [snow]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/snow.gif "snow" [windy]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/windy.gif "windy" [error]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/error.gif "error" [raspberry]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/raspberry.gif "raspberry" [pimoroni_pirate]: https://github.com/LoveBootCaptain/unicornhat_weather_icons/blob/master/animation/HD/pimoroni.gif "pimoroni pirate" [Buy the new Unicorn HAT HD on Pimoroni](https://shop.pimoroni.com/products/unicorn-hat-hd "Buy the new Unicorn HAT HD on Pimoroni") For more animations and icons (also in 8x8 for good old unicorn-hat) please visit and support the original project by LoveBootCaptain: [unicornhat_waether_icons by LoveBootCaptain](https://github.com/LoveBootCaptain/unicornhat_weather_icons "Contribute") unicorn-hat-hd-0.0.4/examples/weather-icons/icons/000077500000000000000000000000001335267313100220405ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/examples/weather-icons/icons/clear-day.png000066400000000000000000000015241335267313100244110ustar00rootroot00000000000000PNG  IHDR`1HIDATxMn1t&QӨ)>6[.mwWMP%M¯㉓V*Fy,eʞ#in -;t:V{ʏ_&=OZF.0]pl#s矛_~_=;^v`?ZT6;lK`jK(6_~_ xf |Lvx<6yG\(X7/{d/2%P9t>`@l5Tn۳`iw2M_~嗿ejoqXOun|?Yeqbasz>l<'-/W Bس$.gLkwabn"aW1a#T49y_~o?\'[VzK;z}?p9_8+Ɯ{P// ߪR߬ogHom_S Kabet,s/2xeW+(’FNt5žEl Ka 9k_~o*>DR@ocX؇מhL=JCO[֏6//~ ` <'^XV[ Ƶ I&ܱs;gf/2h/Cu~(P~ _~O`ks//#"lcuIENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/icons/clear-night.png000066400000000000000000000030361335267313100247450ustar00rootroot00000000000000PNG  IHDR`1HIDATxr7@&iSSLųI8qd{5oCb'~Y4E*I-2RUG6`J]_Ç͛?k߼~U]ǯuM:}o;k1~$%$Bz:<{1<"BGG7>~wn2c_nu_[H(֒ 1XT 5qteO~LQLpR%y>&e,9?{Ow_;$?fH)2u10j@nfW[CYNb%bDDhc EQ8;w=_%;w)5oe2P-[=C_7?x eQpiIJi9%2ڶEDBhD]|EU oLfeu"ygK"Bka>S1Lcn߾MY1{RL"B4P764VԿW_={c-Zbfd>:Ӷ->}NWҌ d[c(Ȳ Cu2ig70LȲ&!nU_ kcËc4:4 ?s<Ȳ_LcȲl="ƬyqѶ&iǯտW{!c 1R7 !^_mC9:8^s+"Ĕ.Z-տW_xF\-Eboy~aA. < H,X."ƈwu@E>㻮[ZK =8տW_>XA;}BUl۾zqNGRa8k5~]׭*@>EX.տW_w||w#e~х8==Ye4Sݒׯ^q||6w^uub 1P]B*ŋ~>^񁺮 !h{~oOӿ!b,sfo}š>KpaYex=sކaq89o1ն ǞEWNpHU 8 տW_뀿rcUUX '_xG[D۴PQ_o嘏W"BIJ]"M쏎~տ/z2TrG@lO/B~տ}7r]SkC6IENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/icons/cloudy.png000066400000000000000000000045371335267313100240560ustar00rootroot00000000000000PNG  IHDR`1H &IDATxil "!PPU7!%h_TEUC!AEH(!((U+UjPS[*U+@*i(m#pp6%9{dw<fg8 "r!r|FL,@4nF:*,K/_^@&alla,k G}i{-7*K/__d2.^0ma"( mcMWK/K/gLJǏ'L:DH$B(8i\wu:uCz饗^z/ 7@,#um۶qp8\E>>L&߶mom۶@ϿX,j(KE"z+(Gq u]," 133,'Ie(Tk_(Fqx㍮Ғo|>_cKRvr;: VϿKE"@<{?W2:hX,eY8(B(B4jrJ~rxJb1|0 bsŮ|T-;֭[;Jem'Opmj * gϞ`ǎM};띿in5;wӧK/}^d͟)rBm~/O_RA}駟n heY-b6e0P(H$(]\.G"@ubWު|@___G~iiiV|M6 ~4e~~zofSi~!xh4J6%L񭶫iT*55peYeYLNNR(jH/ĄKBZ OXʿ5MS(ssPڿEP ﶂ8j54SSSdYx)}V59p?8thcU{֛uH,J(PP/.qwf5|X[/}D"Ѳƿj[sĉ5#K/'4Dλv??#Do !q@{mwT ٰaC/Ciٶg ͛fca_Y{~o䏇_}6RCodaaa+5co߾T*ղƥ!rOtO/O${"G_;hv;uVv+N}W&AQplg:߻?LFBO@z饗'<}?un.#Drlf<ܕ__vh,%h[[_> E**rY\RR[hO<8F\.`.X6L K/{<{"W_g}/U.vIENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/icons/error.png000066400000000000000000000061421335267313100237020ustar00rootroot00000000000000PNG  IHDR`1H )IDATxmlTUt3VK.KXCi05/ba5?]MFԕ5_ эIdQjt%};eΙwM6{޹ߙsy-7p7qhi.]EzY.k?Ohhyy)o4Kn GiAbdy^w*.S7죉c\~ڿf'_  )k?ȿYRi&垲_www}0: @6 06~\Qsd9AX[U,MŠSR@ic3:W}Џ~&K^ci>ϑC>Ʊ2ψa/O%8II7:a>,?;Af).Sh B GGj(F'$טqRo8[{eӨhYv O04L3A zx|dGd^= D>Ʊek ?]]M?ࣣYӃu~f7:Yf:?FOJw{T<'Sz (^v{H~...D[w,[ ωDJ/>t>U؄,_9؄DQhYch{}7oyDF ܨ6oy5C˫y~n=z/LշY9gC (xQ0fg>ghP~ /dFKp){?å4^̡%GI ࿟>jBhb!GYbyv||=c5>?ͫi$*S=rSF3؀bˉM lV#V9y-N|tZ%x| oz?H'l9Հ|1x>| Bm,0Вzu&n7z?y-gײ@K*dWV+dT+kkUL&]#VYG15 ԡLϻp#3,빩3)ޯoR{ݖWFVen߂#U֑(xQO~*[sz/$ JMo$!(A$w#w#HgySL6VYeXEx ((A$SS F(A,-ye[$7J`?Clds;[wjqo:qomF>X/(DŽWWVٮH( F ">[nF-mjͺ3D%KoW[ o~ C Do[Ϛ1Ĉ+߮|.j={8(߮> g.3=s~zY.r~:}#im){XNj@4ܙ}K?oWo`ǎ3y^eZ]~ 'ݺbbY'P( hXݒVu/ J$_>k2DŽžA žqNo4 7žEA|ž՛. ˋ}hT/Hʋ}31g}",/ b[ayoPKybߠ9(˿MQ X/w6B9Qt2B7d0RoaRϐˆߠ‘) :!gwo0Dlm7?ٶ`7d[t6B8Holoߠ®c\]].e;?7RG}_]^}?$Ϳ4Ȝo-5[ 1a@X(QTEQNE;_7( v(*EV(*>`'/ v?/Y`*Eu40(z%zS%NPbb: 4Ѿtq`B!tJq``:rD%PGfZAAt hlJs zh3YǁAK dԌ@Ͽ/YЏ]$A?e1v5fN Q2Umo$Vf"j f25@j{~YЏ]iF"jV{Z_ȏPլL[Nx|YoYtjhj^ʬL[Nq-aeE~\DZ&ee7 T+,규}Q4Cj~AjѾ4Z"keESJXdQ?/hf-$3lyP%d˃*d˃*VyV/J23~ɖUK<̌_Adf-$3lyPed˃*`f-$3?%[TI.˿?e\rʕ18] mAqoۼ¼߶!o0]/mWG)mWWoMvuqom +yj¼v?D"jd X[ hH]wi +zw}N%LҴBž<:v} #rIENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/icons/fog.png000066400000000000000000000113711335267313100233240ustar00rootroot00000000000000PNG  IHDR`1HIDATx[$y[ߧ{gvg%6 &88l%$q؊ˊ8R,S8"[Q!G ƻ ]؝ݙV_rNgCeQ9uFtMk_J)T÷'BO>$?_WS_җ&VgWN4!4 1y~{Gy V<A@ӧ8K5} '_>ɉ'BODJ[o ?PRU\)k5/ /=z4@a=9t} v"B9s fsT*{xH$uHh& f~g2}ۙj7ͩP(P(ȤH&A(F#Hv;U  ELd2R`4KA~?/ eJ%Rb82Pz躆3vRvF{V} /J* $a>A u Oz(8z=<DX"b'^I0L$(HȀagg|Tb>#H"pQ`^}B)t{]@eF1ߪoM5²,eb}+@~`8Tp:NIGQ˲X.z?x (5i_yhR)%V[[5^|Ze1gB*2-T(BdV٬mueKSz>nwT?C!#w!O} 7UMɉx1 7K(8qu\+s{69_4L@г{1"LO빸xO!4 zM"t:̓>z~T Mg!7zdjų>w݅a<ȣrYnܱK#™gX;t`o8)jqiL'H>qu]|G*<9j1V}V0t"lv0RR gdxNm(Z>dbg~/O;s9wo4nv'8>L\%LL6vNM4LT2ő#GYY^&;%.z4[MڝF˴"e=NyL̊0P2,o麾W۶iwhj5RT$!Jyt]'wL`,ce42cTO5}ϟjFS`a|w DP#29.xWH!O4wH>JaY1nz߇†"y $Js?|9nvRl/]ǶmD$:d#d0;^μ~G# Nh6,..Ftt:CXAg10zjv}.m^^$I29䤄({#6ٹ,JJƎōljlmmqH~isSx,y }[lM2Ryf,˚j]1X\,koolzvi2??xvB~ao.?/J&.Jt@AddͅpqLkF<G7tt=9vϞSÇO5۷eeeY|᏾@ɰP MBIgAؽaDx|w'V 4~/t1?v:7_J)>1ˢnSY*3ө S|Èzۭʽ]:R>cVjyA')^x(,H̘őGRکӸPtv?Y1NlZԌ(W*?p0;RݭKpFc|ϧ׵ ^:.:F"7?OXzlCH_Q*qqd/di要I'{sg296#, ~?7?O|d,拼z o=vo_Sя^undsKz^{V20S %8slj dmJhhI?`zx gcNt*L \׍-+F>_$@3t=|di{z6a $Iڝ&~ #y+'L(B $RQ} Dap+pvڭTݚj'MΈFE"GbeuM$6~ 9K[- WJqd9[K䗪\Z_'Oұ{Zƫ^9M07L OJa>V2þ+Ja%$29&c43:g:v#yô0L O[*1aY A Ee[14:Z,N<a" F1R ?f~g2}כjw:ݩn;~6ݕ |;({?5@암@?"vAQR: O^x6n6h0Yh_^Di괸{CoH8W3-?O }޳v#R) D*IkT  xo;n"7 \%$ ôJ1JH$cwyEė>*PѼP( ,RaH%=$n A,GĞ_3?3y~S^gNVt6K"F4b 'ѷ?Q|̊qձd%A<xϗn5oq՟Dť%=Nj.a;W% |#}阦I.0tѐK.𳟾H\v0V" L+\R`8B)0M9,\[5^?sK2JQB`&L|ϣ?Hid2,DnŅo yrxB0Mt:nhz?4 R4eR8>;:23?3QO567677[[Sry?|X3>rix~+ OFSDdy𷸰~_|p*e66xV, !@G+;xisα| JXb]2ƌ w3-T"hsitMf~geSeL5Y1oTl|}o7IENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/icons/partly-cloudy-day.png000066400000000000000000000050161335267313100261330ustar00rootroot00000000000000PNG  IHDR`1H IDATxkWǿGlC1]4C ,lҦ4Ї.J !††f!ӴYv[BH `{s1n3ȖHnӇ\̙HGp<|s7;a„ &Lؾ~[ہ2@ .2EXDH~"Dw8V-@@ |NkẁwdGJS5DϞE[|mXcN "Dn^&n7:vBGxU5yDn_VAs"Dk"㯗߃OoL@AN0;o@my9)~SgEDM{pC?&~OOh7ی`-S8{#tFQ'8i,m,Ӽ?}K l+Re(U-+JQQ"MywmQI(EJs~oE5_=l#d(Soԯ6xz@cN@_b/q|b,cjj-^Qdxx(C3X޳jט`%UU(2~J*k3y(yENփgkٹwT?/ψ&_[ <#~y^_ğ[K#Jơe=ONT7)یgX@~rrZяe|I$Im$!%;v6#JY}SvCCCHRbUUR))OX}[NiԸGs%+7Ngt={4x9=O?&DQSKܙ3YMLԸDfə9$gLV$ 5[bn$g0w-5RonSŮ-y/%x[jomwt:ioUUݻwQ*LbP\{٬jMj5S}lb ɠ^?f/Y{ÇAqkW___wן&,//s?yL='NJ}yµ0>cppq uJK(8ID T*!S_gg1E-JskKSK_ᣇp!Lq+mDˆ D0"ƚS?RdKc}}(OC?3|dWf?Ӟ';fiosx` =O F#Pc VնIe!ӳ8{zd8YJ$ D0:6/>_F7ϐ}5\ʓĉW>/xw53g!/v$1O^";699d}r\BZ-qS`w/ Ϫbp𷮃zꩧԼp @TAĚ">4d{`ꩧzꩧ~{qc "'c@<G4EaTp'$zꩧzꗿ7cY<'xAY;8SO=S!N4o :wlGg>_O߆ꩧ? o9/CE .ex}:Fkk/1$'!""kk;M6˹>6l$k_k{t/:}dzxPO=ɓ =I ?+S1P2@.ɐK2J}?/\Xyߋۋp88ϾrT*X,T*Ual.R)talt;v3[VKg<6}zI'?\WO?A̿EQQ_ADؕ0_o^{:v:܍fӝwvCss38CCC'Eò,+W͕0>>EQ譬~:(x?[z;*]獌sgϛ(Mj\x2zwcccDΝ;Drrܾ}]z20zWȪ Y); T Y)AVe _]###|mb1#c)oUppVŲ,ᰑ\vG?pU:1`Jbx=coOE+Vش;~䫆vSO']?CH/i.?Ǐr~~`xx7ns޽Gn}.C$ 7>ׇH$JL&UU~=K@6iwKFϯK0L]{/>,Dмj%V^x)ν?if`&_`E6cݺuxwoy hmmux%ꩧ߻whe2gzz7o͟Qg [_^8|][-(Rg2yhVd2`Ybx9:ʯn<`%bugΜ5|K|UivٿX< rYE~&`E1eam ,DQtY=cccF˸So᧦֟$IDT*9ZY/?}vNmm* p?yԸƍ41#_N4<nj7,О okP\R dLo|n* %qیs۹###9O=Ltol{GI?!p[$@t@$*CDQnji$I$IrЭ^o {$IFUF߰ ie#~wRдV6"˙f߰am3:> ꩧ[럴Hod?K ,;Э)c/ o@S5ee۟{FSs#B!Pjy1f2qyv]n:663ʯʯԾ~Fd8,`Y{My .ͯV"__zʯsloWS)\볯Fi^zYE݇jL"0j`yQ$Jl=~| b}(zi|5%<3ɁH'O3e]S //////=o>-ziJi7`b-Y|!Qwz9F˦wwy\ܣ?5~qD^^^^^^>zvᓌ%=τ 0tosǯ!Z:9p1_c琗3@|'[;7[doma[/D___@pCr[.Pn۱}Z///////~<K#Z޴9@p2э1qXN2ؼN䗟7OUdᶽtQnGQVٻk$9r/\ǩ]+5'Y͑^D _RWokCbgmā6_k,W~W~W~_m<J/JIENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/icons/rain.png000066400000000000000000000007551335267313100235060ustar00rootroot00000000000000PNG  IHDR /lĘIDATxA@ṩ'wn 2$kkc|ߏ^?랻zzcy͡g5 m79.0-GڼjH?\@ngHWͣi\=AO[`Zy<?jwZgHWͣ:p< ϑ6G=^ROF;G=olT^HHpg"="<~+$?77O=wlX_^ⱒE@G:)xL\]!ߑ"2rqC]2ṭ \-˥ϕlzW 8Wy|]kvervDpXCa̫ 7!?ȾTTi&bzHs[7!<&8«DKA%-6 ?,9=n4m@^7_1;.+K1t*(A*QI1W." l Rv?6¦Zء$D !l'ۛ·Ÿoƿ5w,ǡra#H` P,E"^5,~$qbTQ'6!pHaҵ<KD`rKIaת\j)7ZWK=N u3ti% Mf=NxlvB% {XN`v$B!)I$PTh9dddH>}/CuyƿoN%0+4dS&u?]7}&Bq#Z1+ͰV? +F˄M Bq!`y/ ʯ.M"_(n .GpVyQBkARDdqj7U~m 0-oƿo_k04n 氀yVo<ΓCo5 h'St),,vBj'1'Qu5ܺyɉXy]ƿƿ%#ͽ=ڸ>!iwV!d D7_U>%ل`*l9f|%W3Z37z2"c9̋˂XO [|0˴63ʠG! X%!Ҧeq)\Sv~'C.2+D(^)_7gƿoom%TN;p&ƪu[z(PO=P~uY"#:y|M WDq$e?iҹgƿoo FoIENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/icons/snow.png000066400000000000000000000013701335267313100235350ustar00rootroot00000000000000PNG  IHDR@IDATx C`OI! tLLn{Yyj>O~֞z.mj%mMg\t.]e}Kbi `Ynu뺎n~,L*x a\.ءi8W_8^r m"2k&ĝ;x9/lEr~~~7~466@nُ.cNnޤQZy Kz0= i3 #}a˚/ pDX8#yXGg2>KX| =&ƾGdۺK\csY8.⭖Țwrrp~~~7:CaD"8܌Pg8Qmw~Vz~՛<*r[r^2{TL?+}~6}\**ׇ8([">rKS}~%ùmSpdU'( -qLm$C|PmRJοY}Tr}xnas3\!pI9;Ӄl~/Xߟj[*徿Jd~QQFo>Tq?3 HV}kُh4 /~_9؇IENDB`unicorn-hat-hd-0.0.4/examples/weather-icons/weather-icons.py000077500000000000000000000112021335267313100240460ustar00rootroot00000000000000#!/usr/bin/env python # The MIT License (MIT) # # Copyright (c) 2016 LoveBootCaptain # # 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. # # **************************************************************** # animated weather icons for the unicorn-hat-hd by LovebootCaptain # **************************************************************** # # The icons in the /icons folder are made of 32-36 individual 16x16 images combined to a sprite. # # draw_animation(image) is same as in the 'show-png' example but put into a tiny little function. # Put in your image object and you're done. The function will loop through all images in the sprite # and it will look like a tiny animation. Awesome !! # # You can change the 'fps' with changing the 'cycle_time' variable (0.25 is very smooth) # # loop() finally loops through all png images in a folder (you might guessed it) so you can see all possibilities. # # usage: # # 'weather-icons.py loop' for all animations or images # # 'weather-icons.py clear-day.png' for a single animation or image import os import time from sys import exit, argv try: from PIL import Image except ImportError: exit('This script requires the pillow module\nInstall with: sudo pip install pillow') import unicornhathd as unicorn print(""" **************************************************************** animated weather icons for the unicorn-hat-hd by LovebootCaptain **************************************************************** """) unicorn.brightness(1) unicorn.rotation(0) folder_path = 'icons/' icon_extension = '.png' width, height = unicorn.get_shape() cycle_time = 0.25 def help(): print(""" Usage: python weather-icons.py options options: loop image-file.png example: weather-icons.py loop weather-icons.py clear-day.png try one of the files from this list: {} """.format(', '.join(os.listdir(folder_path)))) def draw_animation(image): # this is the original pimoroni function for drawing sprites try: for o_x in range(int(image.size[0] / width)): for o_y in range(int(image.size[1] / height)): valid = False for x in range(width): for y in range(height): pixel = image.getpixel(((o_x * width) + y, (o_y * height) + x)) r, g, b = int(pixel[0]), int(pixel[1]), int(pixel[2]) if r or g or b: valid = True unicorn.set_pixel(x, y, r, g, b) if valid: unicorn.show() time.sleep(cycle_time) except KeyboardInterrupt: unicorn.off() def loop(): print('Looping through all images in folder {}\n' 'CRL+C to skip image'.format(folder_path)) try: for img_file in os.listdir(folder_path): if img_file.endswith(icon_extension): print('Drawing image: {}'.format(folder_path + img_file)) img = Image.open(folder_path + img_file) draw_animation(img) else: print('Not using this file, might be not an image: {}'.format(img_file)) except KeyboardInterrupt: unicorn.off() unicorn.off() def weather_icons(): try: if argv[1] == 'loop': loop() elif argv[1] in os.listdir(folder_path): print('Drawing Image: {}'.format(argv[1])) img = Image.open(folder_path + argv[1]) draw_animation(img) unicorn.off() else: help() except IndexError: help() if __name__ == '__main__': weather_icons() unicorn-hat-hd-0.0.4/library/000077500000000000000000000000001335267313100160035ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/library/.coveragerc000066400000000000000000000000561335267313100201250ustar00rootroot00000000000000[run] source = unicornhathd omit = .tox/* unicorn-hat-hd-0.0.4/library/CHANGELOG.txt000066400000000000000000000004301335267313100200300ustar00rootroot000000000000000.0.4 ----- * Added support for display addressing (for Ubercorn) 0.0.3 ----- * Deferred IO setup until first call to show * Changed sys.exit to ImportError for warning about missing dependencies 0.0.2 ----- * Tweaked Python package MANIFEST 0.0.1 ----- * Initial release unicorn-hat-hd-0.0.4/library/LICENSE.txt000066400000000000000000000020671335267313100176330ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2017 Pimoroni Ltd 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. unicorn-hat-hd-0.0.4/library/MANIFEST.in000066400000000000000000000001621335267313100175400ustar00rootroot00000000000000include CHANGELOG.txt include LICENSE.txt include README.rst include setup.py recursive-include unicornhathd *.py unicorn-hat-hd-0.0.4/library/README.md000066400000000000000000000000451335267313100172610ustar00rootroot00000000000000# Unicorn HAT HD Pure Python Library unicorn-hat-hd-0.0.4/library/README.rst000066400000000000000000000060461335267313100175000ustar00rootroot00000000000000|Unicorn HAT HD| http://shop.pimoroni.com/products/unicorn-hat-hd |Build Status| |Coverage Status| |PyPi Package| |Python Versions| Installing ---------- Full install (recommended): ~~~~~~~~~~~~~~~~~~~~~~~~~~~ We've created an easy installation script that will install all pre-requisites and get your Unicorn HAT HD up and running with minimal efforts. To run it, fire up Terminal which you'll find in Menu -> Accessories -> Terminal on your Raspberry Pi desktop, as illustrated below: .. figure:: http://get.pimoroni.com/resources/github-repo-terminal.png :alt: Finding the terminal Finding the terminal In the new terminal window type the command exactly as it appears below (check for typos) and follow the on-screen instructions: .. code:: bash curl https://get.pimoroni.com/unicornhathd | bash If you choose to download examples you'll find them in ``/home/pi/Pimoroni/unicornhathd/``. To prototype and try out your code without having to deploy it onto a Raspberry Pi every time, you can use the `Unicorn HAT simulator `__ to run a mock Unicorn HAT on your computer. Manual install: ~~~~~~~~~~~~~~~ SPI needs to be enabled to communicate with the Unicorn Hat HD. If the SPI on your Pi is not enabled or you are unsure if it is: .. code:: bash sudo raspi-config nonint do_spi 0 sudo reboot Library install for Python 3: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: bash sudo apt-get install python3-pip python3-dev python3-spidev sudo pip3 install unicornhathd Library install for Python 2: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: bash sudo apt-get install python-pip python-dev python-spidev sudo pip install unicornhathd Development: ~~~~~~~~~~~~ If you want to contribute, or like living on the edge of your seat by having the latest code, you should clone this repository, ``cd`` to the library directory, and run: .. code:: bash sudo apt-get install python-dev python-setuptools sudo python3 setup.py install (or ``sudo python setup.py install`` whichever your primary Python environment may be) In all cases you will have to enable the SPI bus. Documentation & Support ----------------------- - Guides and tutorials - https://learn.pimoroni.com/unicorn-hat-hd - Function reference - http://docs.pimoroni.com/unicornhathd/ - GPIO Pinout - http://pinout.xyz/pinout/unicorn\_hat\_hd - Get help - http://forums.pimoroni.com/c/support .. |Unicorn HAT HD| image:: unicorn-hat-hd-logo.png .. |Build Status| image:: https://travis-ci.com/pimoroni/unicorn-hat-hd.svg?branch=master :target: https://travis-ci.com/pimoroni/unicorn-hat-hd .. |Coverage Status| image:: https://coveralls.io/repos/github/pimoroni/unicorn-hat-hd/badge.svg?branch=master :target: https://coveralls.io/github/pimoroni/unicorn-hat-hd?branch=master .. |PyPi Package| image:: https://img.shields.io/pypi/v/unicornhathd.svg :target: https://pypi.python.org/pypi/unicornhathd .. |Python Versions| image:: https://img.shields.io/pypi/pyversions/unicornhathd.svg :target: https://pypi.python.org/pypi/unicornhathd unicorn-hat-hd-0.0.4/library/setup.cfg000066400000000000000000000001351335267313100176230ustar00rootroot00000000000000[flake8] exclude = test.py .tox, .eggs, .git, __pycache__, build, dist ignore = E501 unicorn-hat-hd-0.0.4/library/setup.py000077500000000000000000000041371335267313100175250ustar00rootroot00000000000000#!/usr/bin/env python """ Copyright (c) 2017 Pimoroni. 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. """ try: from setuptools import setup except ImportError: from distutils.core import setup classifiers = ['Development Status :: 5 - Production/Stable', 'Operating System :: POSIX :: Linux', 'License :: OSI Approved :: MIT License', 'Intended Audience :: Developers', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Topic :: Software Development', 'Topic :: System :: Hardware'] setup( name='unicornhathd', version='0.0.4', author='Philip Howard', author_email='phil@pimoroni.com', description="""Python library for driving Pimoroni Unicorn HAT HD""", long_description=open('README.rst').read() + '\n' + open('CHANGELOG.txt').read(), license='MIT', keywords='Raspberry Pi LED', url='http://www.pimoroni.com', classifiers=classifiers, py_modules=[], packages=['unicornhathd'], install_requires=['spidev'] ) unicorn-hat-hd-0.0.4/library/tests/000077500000000000000000000000001335267313100171455ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/library/tests/test_setup.py000066400000000000000000000004001335267313100217100ustar00rootroot00000000000000"""Test various import and setup routines.""" import sys import mock def test_setup(): """Test that the library sets up correctly with numpy and spidev.""" sys.modules['spidev'] = mock.MagicMock() import unicornhathd unicornhathd.setup() unicorn-hat-hd-0.0.4/library/tox.ini000066400000000000000000000006141335267313100173170ustar00rootroot00000000000000[tox] envlist = py{27,35},qa skip_missing_interpreters = True [testenv] commands = python setup.py install coverage run -m py.test -v -r wsx coverage report deps = mock pytest>=3.1 pytest-cov numpy [testenv:qa] commands = flake8 --ignore E501 flake8 ../examples rstcheck README.rst deps = flake8 flake8-docstrings flake8-quotes rstcheck unicorn-hat-hd-0.0.4/library/unicornhathd/000077500000000000000000000000001335267313100204715ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/library/unicornhathd/__init__.py000066400000000000000000000152201335267313100226020ustar00rootroot00000000000000#!/usr/bin/env python """Unicorn HAT HD library. Drive the 16x16 RGB pixel Pimoronu Unicorn HAT HD over SPI from a Raspberry Pi or compatible platform. """ import colorsys import time try: import spidev except ImportError: raise ImportError('This library requires the spidev module\nInstall with: sudo pip install spidev') try: import numpy except ImportError: raise ImportError('This library requires the numpy module\nInstall with: sudo pip install numpy') __version__ = '0.0.4' _SOF = 0x72 _DELAY = 1.0 / 120 WIDTH = 16 HEIGHT = 16 PHAT = None HAT = None PHAT_VERTICAL = None AUTO = None PANEL_SHAPE = (16, 16) _rotation = 0 _brightness = 0.5 _buffer_width = 16 _buffer_height = 16 _addressing_enabled = False _buf = numpy.zeros((_buffer_width, _buffer_height, 3), dtype=int) class Display: """Represents a single display in a multi-display chain. Contains the coordinates for the slice of the pixel buffer which should be visible on this particular display. """ def __init__(self, enabled, x, y, rotation): """Initialise display. :param enabled: True/False to indicate if this display is enabled :param x: x offset of display portion in buffer :param y: y offset of display portion in buffer :param rotation: rotation of display """ self.enabled = enabled self.update(x, y, rotation) def update(self, x, y, rotation): """Update display position. :param x: x offset of display portion in buffer :param y: y offset of display portion in buffer :param rotation: rotation of display """ self.x = x self.y = y self.rotation = rotation def get_buffer_window(self, source): """Grab the correct portion of the supplied buffer for this display. :param source: source buffer, should be a numpy array """ view = source[self.x:self.x + PANEL_SHAPE[0], self.y:self.y + PANEL_SHAPE[1]] return numpy.rot90(view, self.rotation + 1) _displays = [Display(False, 0, 0, 0) for _ in range(8)] is_setup = False def setup(): """Initialize Unicorn HAT HD.""" global _spi, _buf, is_setup if is_setup: return _spi = spidev.SpiDev() _spi.open(0, 0) _spi.max_speed_hz = 9000000 is_setup = True def enable_addressing(enabled=True): """Enable multi-panel addressing support (for Ubercorn).""" global _addressing_enabled _addressing_enabled = enabled def setup_buffer(width, height): """Set up the internal pixel buffer. :param width: width of buffer, ideally in multiples of 16 :param height: height of buffer, ideally in multiples of 16 """ global _buffer_width, _buffer_height, _buf _buffer_width = width _buffer_height = height _buf = numpy.zeros((_buffer_width, _buffer_height, 3), dtype=int) def enable_display(address, enabled=True): """Enable a single display in the chain. :param address: address of the display from 0 to 7 :param enabled: True/False to indicate display is enabled """ _displays[address].enabled = enabled def setup_display(address, x, y, rotation): """Configure a single display in the chain. :param x: x offset of display portion in buffer :param y: y offset of display portion in buffer :param rotation: rotation of display """ _displays[address].update(x, y, rotation) enable_display(address) def brightness(b): """Set the display brightness between 0.0 and 1.0. :param b: Brightness from 0.0 to 1.0 (default 0.5) """ global _brightness _brightness = b def rotation(r): """Set the display rotation in degrees. Actual rotation will be snapped to the nearest 90 degrees. """ global _rotation _rotation = int(round(r / 90.0)) def get_rotation(): """Return the display rotation in degrees.""" return _rotation * 90 def set_layout(pixel_map=None): """Do nothing, for library compatibility with Unicorn HAT.""" pass def set_all(r, g, b): """Set all pixels to RGB colour. :param r: Amount of red from 0 to 255 :param g: Amount of green from 0 to 255 :param b: Amount of blue from 0 to 255 """ _buf[:] = r, g, b def set_pixel(x, y, r, g, b): """Set a single pixel to RGB colour. :param x: Horizontal position from 0 to 15 :param y: Veritcal position from 0 to 15 :param r: Amount of red from 0 to 255 :param g: Amount of green from 0 to 255 :param b: Amount of blue from 0 to 255 """ _buf[int(x)][int(y)] = r, g, b def set_pixel_hsv(x, y, h, s=1.0, v=1.0): """Set a single pixel to a colour using HSV. :param x: Horizontal position from 0 to 15 :param y: Veritcal position from 0 to 15 :param h: Hue from 0.0 to 1.0 ( IE: degrees around hue wheel/360.0 ) :param s: Saturation from 0.0 to 1.0 :param v: Value (also known as brightness) from 0.0 to 1.0 """ r, g, b = [int(n * 255) for n in colorsys.hsv_to_rgb(h, s, v)] set_pixel(x, y, r, g, b) def get_pixel(x, y): """Get pixel colour in RGB as a tuple. :param x: Horizontal position from 0 to 15 :param y: Veritcal position from 0 to 15 """ return tuple(_buf[int(x)][int(y)]) def shade_pixels(shader): """Set all pixels to a colour determined by a shader function. :param shader: function that accepts x/y position and returns an r,g,b tuple. """ for x in range(WIDTH): for y in range(HEIGHT): r, g, b = shader(x, y) set_pixel(x, y, r, g, b) def get_pixels(): """Return entire buffer.""" return _buf def get_shape(): """Return the shape (width, height) of the display.""" return _buffer_width, _buffer_height def clear(): """Clear the buffer.""" _buf.fill(0) def off(): """Clear the buffer and immediately update Unicorn HAT HD. Turns off all pixels. """ clear() show() def show(): """Output the contents of the buffer to Unicorn HAT HD.""" setup() if _addressing_enabled: for address in range(8): display = _displays[address] if display.enabled: if _buffer_width == _buffer_height or _rotation in [0, 2]: window = display.get_buffer_window(numpy.rot90(_buf, _rotation)) else: window = display.get_buffer_window(numpy.rot90(_buf, _rotation)) _spi.xfer2([_SOF + 1 + address] + (window.reshape(768) * _brightness).astype(numpy.uint8).tolist()) time.sleep(_DELAY) else: _spi.xfer2([_SOF] + (numpy.rot90(_buf, _rotation).reshape(768) * _brightness).astype(numpy.uint8).tolist()) time.sleep(_DELAY) unicorn-hat-hd-0.0.4/packaging/000077500000000000000000000000001335267313100162635ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/packaging/CHANGELOG000066400000000000000000000012541335267313100174770ustar00rootroot00000000000000unicornhathd (0.0.4) stable; urgency=low * Added support for display addressing (for Ubercorn) -- Phil Howard Wed, 26 Sep 2018 00:00:00 +0000 unicornhathd (0.0.3) stable; urgency=low * Deferred IO setup until first call to show * Changed sys.exit to ImportError for warning about missing dependencies -- Phil Howard Wed, 18 Oct 2017 00:00:00 +0000 unicornhathd (0.0.2) stable; urgency=low * Tweaked Python package MANIFEST -- Phil Howard Fri, 16 Jun 2017 00:00:00 +0000 unicornhathd (0.0.1) stable; urgency=low * Initial release -- Phil Howard Mon, 5 Jun 2017 00:00:00 +0000 unicorn-hat-hd-0.0.4/packaging/debian/000077500000000000000000000000001335267313100175055ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/packaging/debian/README000066400000000000000000000006241335267313100203670ustar00rootroot00000000000000README Unicorn HAT HD provides a matrix of 256 RGB LED pixels. It's ideal for writing messages, showing graphs, and drawing pictures. Learn more: https://shop.pimoroni.com/products/unicorn-hat-hd For examples run: `curl -sS get.pimoroni.com/unicornhathd | bash` IMPORTANT Unicorn HAT HD requires SPI. To enable run `curl get.pimoroni.com/spi | bash` or use raspi-config and reboot your Raspberry Pi. unicorn-hat-hd-0.0.4/packaging/debian/changelog000066400000000000000000000012541335267313100213610ustar00rootroot00000000000000unicornhathd (0.0.4) stable; urgency=low * Added support for display addressing (for Ubercorn) -- Phil Howard Wed, 26 Sep 2018 00:00:00 +0000 unicornhathd (0.0.3) stable; urgency=low * Deferred IO setup until first call to show * Changed sys.exit to ImportError for warning about missing dependencies -- Phil Howard Wed, 18 Oct 2017 00:00:00 +0000 unicornhathd (0.0.2) stable; urgency=low * Tweaked Python package MANIFEST -- Phil Howard Fri, 16 Jun 2017 00:00:00 +0000 unicornhathd (0.0.1) stable; urgency=low * Initial release -- Phil Howard Mon, 5 Jun 2017 00:00:00 +0000 unicorn-hat-hd-0.0.4/packaging/debian/clean000066400000000000000000000000151335267313100205060ustar00rootroot00000000000000*.egg-info/* unicorn-hat-hd-0.0.4/packaging/debian/compat000066400000000000000000000000021335267313100207030ustar00rootroot000000000000009 unicorn-hat-hd-0.0.4/packaging/debian/control000066400000000000000000000021531335267313100211110ustar00rootroot00000000000000Source: unicornhathd Maintainer: Phil Howard Homepage: https://github.com/pimoroni/unicorn-hat-hd Section: python Priority: extra Build-Depends: debhelper (>= 9.0.0), dh-python, python-all (>= 2.7), python-setuptools, python3-all (>= 3.4), python3-setuptools Standards-Version: 3.9.6 X-Python-Version: >= 2.7 X-Python3-Version: >= 3.4 Package: python-unicornhathd Architecture: all Section: python Depends: ${misc:Depends}, ${python:Depends}, python-spidev, python-numpy Suggests: Description: Python library for the Pimoroni Unicorn HAT HD. Unicorn HAT HD provides a matrix of 256 RGB LED pixels. It's ideal for writing messages, showing graphs, and drawing pictures. . This is the Python 2 version of the package. Package: python3-unicornhathd Architecture: all Section: python Depends: ${misc:Depends}, ${python3:Depends}, python3-spidev, python3-numpy Suggests: Description: Python library for the Pimoroni Unicorn HAT HD. Unicorn HAT HD provides a matrix of 256 RGB LED pixels. It's ideal for writing messages, showing graphs, and drawing pictures. . This is the Python 3 version of the package. unicorn-hat-hd-0.0.4/packaging/debian/copyright000066400000000000000000000024011335267313100214350ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: unicornhathd Source: https://github.com/pimoroni/unicorn-hat-hd Files: * Copyright: 2017 Pimoroni Ltd License: MIT License: MIT 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. unicorn-hat-hd-0.0.4/packaging/debian/docs000066400000000000000000000000001335267313100203460ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/packaging/debian/rules000077500000000000000000000005141335267313100205650ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- #export DH_VERBOSE=1 export DH_OPTIONS %: dh $@ --with python2,python3 --buildsystem=python_distutils override_dh_auto_install: python setup.py install --root debian/python-unicornhathd --install-layout=deb python3 setup.py install --root debian/python3-unicornhathd --install-layout=deb unicorn-hat-hd-0.0.4/packaging/debian/source/000077500000000000000000000000001335267313100210055ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/packaging/debian/source/format000066400000000000000000000000151335267313100222140ustar00rootroot000000000000003.0 (native) unicorn-hat-hd-0.0.4/packaging/debian/source/options000066400000000000000000000000511335267313100224170ustar00rootroot00000000000000extend-diff-ignore = "^[^/]+\.egg-info/" unicorn-hat-hd-0.0.4/packaging/makeall.sh000077500000000000000000000101171335267313100202300ustar00rootroot00000000000000#!/bin/bash # script control variables reponame="" # leave this blank for auto-detection libname="" # leave this blank for auto-detection packagename="" # leave this blank for auto-selection debianlog="debian/changelog" debcontrol="debian/control" debcopyright="debian/copyright" debrules="debian/rules" debreadme="debian/README" debdir="$(pwd)" rootdir="$(dirname $debdir)" libdir="$rootdir/library" FLAG=false # function define success() { echo "$(tput setaf 2)$1$(tput sgr0)" } inform() { echo "$(tput setaf 6)$1$(tput sgr0)" } warning() { echo "$(tput setaf 1)$1$(tput sgr0)" } newline() { echo "" } # assessing repo and library variables if [ -z "$reponame" ] || [ -z "$libname" ]; then inform "detecting reponame and libname..." else inform "using reponame and libname overrides" fi if [ -z "$reponame" ]; then if [[ $rootdir == *"python"* ]]; then repodir="$(dirname $rootdir)" reponame="$(basename $repodir)" else repodir="$rootdir" reponame="$(basename $repodir)" fi reponame=$(echo "$reponame" | tr "[A-Z]" "[a-z]") fi if [ -z "$libname" ]; then cd "$libdir" libname=$(grep "name" setup.py | tr -d "[:space:]" | cut -c 7- | rev | cut -c 3- | rev) libname=$(echo "$libname" | tr "[A-Z]" "[a-z]") && cd "$debdir" fi if [ -z "$packagename" ]; then packagename="$libname" fi echo "reponame is $reponame and libname is $libname" echo "output packages will be python-$packagename and python3-$packagename" # checking generating changelog file ./makelog.sh version=$(head -n 1 "$libdir/CHANGELOG.txt") echo "building $libname version $version" # checking debian/changelog file inform "checking debian/changelog file..." if ! head -n 1 $debianlog | grep "$libname" &> /dev/null; then warning "library not mentioned in header!" && FLAG=true elif head -n 1 $debianlog | grep "UNRELEASED"; then warning "this changelog is not going to generate a release!" warning "change distribution to 'stable'" && FLAG=true fi # checking debian/copyright file inform "checking debian/copyright file..." if ! grep "^Source" $debcopyright | grep "$reponame" &> /dev/null; then warning "$(grep "^Source" $debcopyright)" && FLAG=true fi if ! grep "^Upstream-Name" $debcopyright | grep "$libname" &> /dev/null; then warning "$(grep "^Upstream-Name" $debcopyright)" && FLAG=true fi # checking debian/control file inform "checking debian/control file..." if ! grep "^Source" $debcontrol | grep "$libname" &> /dev/null; then warning "$(grep "^Source" $debcontrol)" && FLAG=true fi if ! grep "^Homepage" $debcontrol | grep "$reponame" &> /dev/null; then warning "$(grep "^Homepage" $debcontrol)" && FLAG=true fi if ! grep "^Package: python-$packagename" $debcontrol &> /dev/null; then warning "$(grep "^Package: python-" $debcontrol)" && FLAG=true fi if ! grep "^Package: python3-$packagename" $debcontrol &> /dev/null; then warning "$(grep "^Package: python3-" $debcontrol)" && FLAG=true fi if ! grep "^Priority: extra" $debcontrol &> /dev/null; then warning "$(grep "^Priority" $debcontrol)" && FLAG=true fi # checking debian/rules file inform "checking debian/rules file..." if ! grep "debian/python-$packagename" $debrules &> /dev/null; then warning "$(grep "debian/python-" $debrules)" && FLAG=true fi if ! grep "debian/python3-$packagename" $debrules &> /dev/null; then warning "$(grep "debian/python3-" $debrules)" && FLAG=true fi # checking debian/README file inform "checking debian/readme file..." if ! grep -e "$libname" -e "$reponame" $debreadme &> /dev/null; then warning "README does not seem to mention product, repo or lib!" && FLAG=true fi # summary of checks pre build if $FLAG; then warning "Check all of the above and correct!" && exit 1 else inform "we're good to go... bulding!" fi # building deb and final checks ./makedeb.sh inform "running lintian..." lintian -v $(find -name "python*$version*.deb") lintian -v $(find -name "python3*$version*.deb") inform "checking signatures..." gpg --verify $(find -name "*$version*changes") gpg --verify $(find -name "*$version*dsc") exit 0 unicorn-hat-hd-0.0.4/packaging/makedeb.sh000077500000000000000000000023101335267313100202060ustar00rootroot00000000000000#!/bin/bash gettools="no" # if set to yes downloads the tools required setup="yes" # if set to yes populates library folder buildeb="yes" # if set to yes builds the deb files cleanup="yes" # if set to yes cleans up build files pkgfiles=( "build" "changes" "deb" "dsc" "tar.xz" ) if [ $gettools == "yes" ]; then sudo apt-get update && sudo apt-get install build-essential debhelper devscripts dh-make dh-python dput gnupg sudo apt-get install python-all python-setuptools python3-all python3-setuptools sudo apt-get install python-mock python-sphinx python-sphinx-rtd-theme sudo pip install Sphinx --upgrade && sudo pip install sphinx_rtd_theme --upgrade fi if [ $setup == "yes" ]; then rm -R ../library/build ../library/debian &> /dev/null cp -R ./debian ../library/ && cp -R ../sphinx ../library/doc fi cd ../library if [ $buildeb == "yes" ]; then debuild -aarmhf for file in ${pkgfiles[@]}; do rm ../packaging/*.$file &> /dev/null mv ../*.$file ../packaging done rm -R ../documentation/html &> /dev/null cp -R ./build/sphinx/html ../documentation fi if [ $cleanup == "yes" ]; then debuild clean rm -R ./build ./debian ./doc &> /dev/null fi exit 0 unicorn-hat-hd-0.0.4/packaging/makedoc.sh000077500000000000000000000022101335267313100202200ustar00rootroot00000000000000#!/bin/bash gettools="no" # if set to yes downloads the tools required setup="yes" # if set to yes populates library folder buildoc="yes" # if set to yes builds the deb files cleanup="yes" # if set to yes cleans up build files pkgfiles=( "build" "changes" "deb" "dsc" "tar.xz" ) if [ $gettools == "yes" ]; then sudo apt-get update && sudo apt-get install build-essential debhelper devscripts dh-make dh-python sudo apt-get install python-all python-setuptools python3-all python3-setuptools sudo apt-get install python-mock python-sphinx python-sphinx-rtd-theme sudo pip install Sphinx --upgrade && sudo pip install sphinx_rtd_theme --upgrade fi if [ $setup == "yes" ]; then rm -R ../library/build ../library/debian &> /dev/null cp -R ./debian ../library/ && cp -R ../sphinx ../library/doc fi cd ../library if [ $buildoc == "yes" ]; then debuild for file in ${pkgfiles[@]}; do rm ../*.$file &> /dev/null done rm -R ../documentation/html &> /dev/null cp -R ./build/sphinx/html ../documentation fi if [ $cleanup == "yes" ]; then debuild clean rm -R ./build ./debian ./doc &> /dev/null fi exit 0 unicorn-hat-hd-0.0.4/packaging/makelog.sh000077500000000000000000000041771335267313100202520ustar00rootroot00000000000000#!/bin/bash # script control variables libname="" # leave this blank for auto-detection sibname=() # name of sibling in packages list versionwarn="yes" # set to anything but 'yes' to turn off warning debdir="$(pwd)" rootdir="$(dirname $debdir)" libdir="$rootdir/library" mainlog="CHANGELOG" debianlog="debian/changelog" pypilog="$libdir/CHANGELOG.txt" # function define success() { echo "$(tput setaf 2)$1$(tput sgr0)" } inform() { echo "$(tput setaf 6)$1$(tput sgr0)" } warning() { echo "$(tput setaf 1)$1$(tput sgr0)" } newline() { echo "" } # generate debian changelog cat $mainlog > $debianlog inform "seeded debian changelog" # generate pypi changelog sed -e "/--/d" -e "s/ \*/\*/" \ -e "s/.*\([0-9].[0-9].[0-9]\).*/\1/" \ -e '/[0-9].[0-9].[0-9]/ a\ -----' $mainlog | cat -s > $pypilog version=$(head -n 1 $pypilog) inform "pypi changelog generated" # touch up version in setup.py file if [ -n $(grep version "$libdir/setup.py" &> /dev/null) ]; then inform "touched up version in setup.py" sed -i "s/'[0-9].[0-9].[0-9]'/'$version'/" "$libdir/setup.py" else warning "couldn't touch up version in setup, no match found" fi # touch up version in lib or package siblings if [ -z "$libname" ]; then cd "$libdir" libname=$(grep "name" setup.py | tr -d "[:space:]" | cut -c 7- | rev | cut -c 3- | rev) libname=$(echo "$libname" | tr "[A-Z]" "[a-z]") && cd "$debdir" sibname+=( "$libname" ) elif [ "$libname" != "package" ]; then sibname+=( "$libname" ) fi for sibling in ${sibname[@]}; do if grep -e "__version__" "$libdir/$sibling.py" &> /dev/null; then sed -i "s/__version__ = '[0-9].[0-9].[0-9]'/__version__ = '$version'/" "$libdir/$sibling.py" inform "touched up version in $sibling.py" elif grep -e "__version__" "$libdir/$sibling/__init__.py" &> /dev/null; then sed -i "s/__version__ = '[0-9].[0-9].[0-9]'/__version__ = '$version'/" "$libdir/$sibling/__init__.py" inform "touched up version in $sibling/__init__.py" elif [ "$versionwarn" == "yes" ]; then warning "couldn't touch up __version__ in $sibling, no match found" fi done exit 0 unicorn-hat-hd-0.0.4/projects/000077500000000000000000000000001335267313100161705ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/projects/unicornpaint/000077500000000000000000000000001335267313100207015ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/projects/unicornpaint/.gitignore000066400000000000000000000000071335267313100226660ustar00rootroot00000000000000saves/ unicorn-hat-hd-0.0.4/projects/unicornpaint/paint.py000077500000000000000000000054111335267313100223720ustar00rootroot00000000000000#!/usr/bin/env python import os import stat import threading import time from sys import exit try: from flask import Flask, render_template except ImportError: exit("This script requires the flask module\nInstall with: sudo pip install flask") import unicornhathd PORT = 8000 unicornhathd.rotation(0) width,height=unicornhathd.get_shape() control_panel = """ """ for y in range(height): control_panel += '' for x in range(width): control_panel += '' control_panel += '' control_panel += '
' control_panel += """
  • Lighten
  • Darken
""" app = Flask(__name__) @app.route('/') def home(): return render_template('painthathd.html') @app.route('/save/') def save(filename): try: os.mkdir('saves/') except OSError: pass try: data = unicornhathd.get_pixels() data = repr(data) data = data.replace('array', 'list') print(filename, data) file = open('saves/' + filename + '.py', 'w') file.write("""#!/usr/bin/env python import unicornhathd import signal unicornhathd.rotation(0) pixels = {} for x in range(unicornhathd.WIDTH): for y in range(unicornhathd.HEIGHT): r, g, b = pixels[x][y] unicornhathd.set_pixel(x, y, r, g, b) unicornhathd.show() print("\\nShowing: {}\\nPress Ctrl+C to exit!") signal.pause() """.format(data, filename)) file.close() os.chmod('saves/' + filename + '.py', 0o777 | stat.S_IEXEC) return("ok" + str(unicornhathd.get_pixels())) except AttributeError: print("Unable to save, please update") print("unicornhathdhathd library!") return("fail") @app.route('/clear') def clear(): s = threading.Thread(None,unicornhathd.clear) s.start() return "ok" @app.route('/show') def show(): s = threading.Thread(None,unicornhathd.show) s.start() return "ok" @app.route('/pixel/////') def set_pixel(x, y, r, g, b): x, y, r, g, b = int(x), int(y), int(r), int(g), int(b) unicornhathd.set_pixel(unicornhathd.WIDTH - 1 - x, y, r, g, b) return "ok" if __name__ == "__main__": unicornhathd.brightness(0.5) app.run(host='0.0.0.0', port=PORT, debug=True) unicorn-hat-hd-0.0.4/projects/unicornpaint/static/000077500000000000000000000000001335267313100221705ustar00rootroot00000000000000unicorn-hat-hd-0.0.4/projects/unicornpaint/static/font-awesome.min.css000066400000000000000000000527401335267313100261000ustar00rootroot00000000000000/*! * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}unicorn-hat-hd-0.0.4/projects/unicornpaint/static/jquery-ui.min.js000066400000000000000000006753631335267313100252660ustar00rootroot00000000000000/*! jQuery UI - v1.10.1 - 2013-02-15 * http://jqueryui.com * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js * Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ (function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.10.1",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)}})})(jQuery),function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a={},f=t.split(".")[0];t=t.split(".")[1],i=f+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[f]=e[f]||{},s=e[f][t],o=e[f][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,r){if(!e.isFunction(r)){a[t]=r;return}a[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},i=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=i,s=r.apply(this,arguments),this._super=t,this._superApply=n,s}}()}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},a,{constructor:o,namespace:f,widgetName:t,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})}(jQuery),function(e,t){e.widget("ui.draggable",e.ui.mouse,{version:"1.10.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){this.options.helper==="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var n=this.options;return this.helper||n.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(e(n.iframeFix===!0?"iframe":n.iframeFix).each(function(){e("
").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!=="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!=="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n,r=this,i=!1,s=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),n=this.element[0];while(n&&(n=n.parentNode))n===document&&(i=!0);return!i&&this.options.helper==="original"?!1:(this.options.revert==="invalid"&&!s||this.options.revert==="valid"&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){r._trigger("stop",t)!==!1&&r._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1)},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").addBack().each(function(){this===t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper==="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo==="parent"?this.element[0].parentNode:n.appendTo),r[0]!==this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition==="absolute"&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()==="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition==="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,n,r,i=this.options;i.containment==="parent"&&(i.containment=this.helper[0].parentNode);if(i.containment==="document"||i.containment==="window")this.containment=[i.containment==="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,i.containment==="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(i.containment==="document"?0:e(window).scrollLeft())+e(i.containment==="document"?document:window).width()-this.helperProportions.width-this.margins.left,(i.containment==="document"?0:e(window).scrollTop())+(e(i.containment==="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(i.containment)&&i.containment.constructor!==Array){n=e(i.containment),r=n[0];if(!r)return;t=e(r).css("overflow")!=="hidden",this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(t?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else i.containment.constructor===Array&&(this.containment=i.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t==="absolute"?1:-1,i=this.cssPosition!=="absolute"||this.scrollParent[0]!==document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,s=/(html|body)/i.test(i[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition==="fixed"?-this.scrollParent.scrollTop():s?0:i.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition==="fixed"?-this.scrollParent.scrollLeft():s?0:i.scrollLeft())*r}},_generatePosition:function(t){var n,r,i,s,o=this.options,u=this.cssPosition!=="absolute"||this.scrollParent[0]!==document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(u[0].tagName),f=t.pageX,l=t.pageY;return this.originalPosition&&(this.containment&&(this.relative_container?(r=this.relative_container.offset(),n=[this.containment[0]+r.left,this.containment[1]+r.top,this.containment[2]+r.left,this.containment[3]+r.top]):n=this.containment,t.pageX-this.offset.click.leftn[2]&&(f=n[2]+this.offset.click.left),t.pageY-this.offset.click.top>n[3]&&(l=n[3]+this.offset.click.top)),o.grid&&(i=o.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,l=n?i-this.offset.click.top>=n[1]||i-this.offset.click.top>n[3]?i:i-this.offset.click.top>=n[1]?i-o.grid[1]:i+o.grid[1]:i,s=o.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,f=n?s-this.offset.click.left>=n[0]||s-this.offset.click.left>n[2]?s:s-this.offset.click.left>=n[0]?s-o.grid[0]:s+o.grid[0]:s)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition==="fixed"?-this.scrollParent.scrollTop():a?0:u.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition==="fixed"?-this.scrollParent.scrollLeft():a?0:u.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!==this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,n,r){return r=r||this._uiHash(),e.ui.plugin.call(this,t,[n,r]),t==="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,n,r)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n){var r=e(this).data("ui-draggable"),i=r.options,s=e.extend({},n,{item:r.element});r.sortables=[],e(i.connectToSortable).each(function(){var n=e.data(this,"ui-sortable");n&&!n.options.disabled&&(r.sortables.push({instance:n,shouldRevert:n.options.revert}),n.refreshPositions(),n._trigger("activate",t,s))})},stop:function(t,n){var r=e(this).data("ui-draggable"),i=e.extend({},n,{item:r.element});e.each(r.sortables,function(){this.instance.isOver?(this.instance.isOver=0,r.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,r.options.helper==="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,i))})},drag:function(t,n){var r=e(this).data("ui-draggable"),i=this;e.each(r.sortables,function(){var s=!1,o=this;this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(s=!0,e.each(r.sortables,function(){return this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(o.instance.element[0],this.instance.element[0])&&(s=!1),s})),s?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(i).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return n.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=r.offset.click.top,this.instance.offset.click.left=r.offset.click.left,this.instance.offset.parent.left-=r.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=r.offset.parent.top-this.instance.offset.parent.top,r._trigger("toSortable",t),r.dropped=this.instance.element,r.currentItem=r.element,this.instance.fromOutside=r),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),r._trigger("fromSortable",t),r.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(){var t=e("body"),n=e(this).data("ui-draggable").options;t.css("cursor")&&(n._cursor=t.css("cursor")),t.css("cursor",n.cursor)},stop:function(){var t=e(this).data("ui-draggable").options;t._cursor&&e("body").css("cursor",t._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,n){var r=e(n.helper),i=e(this).data("ui-draggable").options;r.css("opacity")&&(i._opacity=r.css("opacity")),r.css("opacity",i.opacity)},stop:function(t,n){var r=e(this).data("ui-draggable").options;r._opacity&&e(n.helper).css("opacity",r._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(){var t=e(this).data("ui-draggable");t.scrollParent[0]!==document&&t.scrollParent[0].tagName!=="HTML"&&(t.overflowOffset=t.scrollParent.offset())},drag:function(t){var n=e(this).data("ui-draggable"),r=n.options,i=!1;if(n.scrollParent[0]!==document&&n.scrollParent[0].tagName!=="HTML"){if(!r.axis||r.axis!=="x")n.overflowOffset.top+n.scrollParent[0].offsetHeight-t.pageY=0;c--){u=p.snapElements[c].left,a=u+p.snapElements[c].width,f=p.snapElements[c].top,l=f+p.snapElements[c].height;if(!(u-vt&&e=h&&a<=p||f>=h&&f<=p||ap)&&(o>=l&&o<=c||u>=l&&u<=c||oc);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r,i,s=e.ui.ddmanager.droppables[t.options.scope]||[],o=n?n.type:null,u=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(r=0;r").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=u.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor===String){this.handles==="all"&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={};for(n=0;n"),i.css({zIndex:u.zIndex}),"se"===r&&i.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[r]=".ui-resizable-"+r,this.element.append(i)}this._renderAxis=function(t){var n,r,i,s;t=t||this.element;for(n in this.handles){this.handles[n].constructor===String&&(this.handles[n]=e(this.handles[n],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(r=e(this.handles[n],this.element),s=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth(),i=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize());if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=i&&i[1]?i[1]:"se")}),u.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(u.disabled)return;e(this).removeClass("ui-resizable-autohide"),o._handles.show()}).mouseleave(function(){if(u.disabled)return;o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,n=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(n(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),n(this.originalElement),this},_mouseCapture:function(t){var n,r,i=!1;for(n in this.handles){r=e(this.handles[n])[0];if(r===t.target||e.contains(r,t.target))i=!0}return!this.options.disabled&&i},_mouseStart:function(t){var r,i,s,o=this.options,u=this.element.position(),a=this.element;return this.resizing=!0,/absolute/.test(a.css("position"))?a.css({position:"absolute",top:a.css("top"),left:a.css("left")}):a.is(".ui-draggable")&&a.css({position:"absolute",top:u.top,left:u.left}),this._renderProxy(),r=n(this.helper.css("left")),i=n(this.helper.css("top")),o.containment&&(r+=e(o.containment).scrollLeft()||0,i+=e(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:r,top:i},this.size=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.originalPosition={left:r,top:i},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof o.aspectRatio=="number"?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor",s==="auto"?this.axis+"-resize":s),a.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var n,r=this.helper,i={},s=this.originalMousePosition,o=this.axis,u=this.position.top,a=this.position.left,f=this.size.width,l=this.size.height,c=t.pageX-s.left||0,h=t.pageY-s.top||0,p=this._change[o];if(!p)return!1;n=p.apply(this,[t,c,h]),this._updateVirtualBoundaries(t.shiftKey);if(this._aspectRatio||t.shiftKey)n=this._updateRatio(n,t);return n=this._respectSize(n,t),this._updateCache(n),this._propagate("resize",t),this.position.top!==u&&(i.top=this.position.top+"px"),this.position.left!==a&&(i.left=this.position.left+"px"),this.size.width!==f&&(i.width=this.size.width+"px"),this.size.height!==l&&(i.height=this.size.height+"px"),r.css(i),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(i)||this._trigger("resize",t,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n,r,i,s,o,u,a,f=this.options,l=this;return this._helper&&(n=this._proportionallyResizeElements,r=n.length&&/textarea/i.test(n[0].nodeName),i=r&&e.ui.hasScroll(n[0],"left")?0:l.sizeDiff.height,s=r?0:l.sizeDiff.width,o={width:l.helper.width()-s,height:l.helper.height()-i},u=parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left)||null,a=parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top)||null,f.animate||this.element.css(e.extend(o,{top:a,left:u})),l.helper.height(l.size.height),l.helper.width(l.size.width),this._helper&&!f.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,n,i,s,o,u=this.options;o={minWidth:r(u.minWidth)?u.minWidth:0,maxWidth:r(u.maxWidth)?u.maxWidth:Infinity,minHeight:r(u.minHeight)?u.minHeight:0,maxHeight:r(u.maxHeight)?u.maxHeight:Infinity};if(this._aspectRatio||e)t=o.minHeight*this.aspectRatio,i=o.minWidth/this.aspectRatio,n=o.maxHeight*this.aspectRatio,s=o.maxWidth/this.aspectRatio,t>o.minWidth&&(o.minWidth=t),i>o.minHeight&&(o.minHeight=i),ne.width,u=r(e.height)&&t.minHeight&&t.minHeight>e.height,a=this.originalPosition.left+this.originalSize.width,f=this.position.top+this.size.height,l=/sw|nw|w/.test(n),c=/nw|ne|n/.test(n);return o&&(e.width=t.minWidth),u&&(e.height=t.minHeight),i&&(e.width=t.maxWidth),s&&(e.height=t.maxHeight),o&&l&&(e.left=a-t.minWidth),i&&l&&(e.left=a-t.maxWidth),u&&c&&(e.top=f-t.minHeight),s&&c&&(e.top=f-t.maxHeight),!e.width&&!e.height&&!e.left&&e.top?e.top=null:!e.width&&!e.height&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){if(!this._proportionallyResizeElements.length)return;var e,t,n,r,i,s=this.helper||this.element;for(e=0;e"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var n=this.originalSize,r=this.originalPosition;return{left:r.left+t,width:n.width-t}},n:function(e,t,n){var r=this.originalSize,i=this.originalPosition;return{top:i.top+n,height:r.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!=="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var n=e(this).data("ui-resizable"),r=n.options,i=n._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:n.sizeDiff.height,u=s?0:n.sizeDiff.width,a={width:n.size.width-u,height:n.size.height-o},f=parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left)||null,l=parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top)||null;n.element.animate(e.extend(a,l&&f?{top:l,left:f}:{}),{duration:r.animateDuration,easing:r.animateEasing,step:function(){var r={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};i&&i.length&&e(i[0]).css({width:r.width,height:r.height}),n._updateCache(r),n._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var t,r,i,s,o,u,a,f=e(this).data("ui-resizable"),l=f.options,c=f.element,h=l.containment,p=h instanceof e?h.get(0):/parent/.test(h)?c.parent().get(0):h;if(!p)return;f.containerElement=e(p),/document/.test(h)||h===document?(f.containerOffset={left:0,top:0},f.containerPosition={left:0,top:0},f.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(t=e(p),r=[],e(["Top","Right","Left","Bottom"]).each(function(e,i){r[e]=n(t.css("padding"+i))}),f.containerOffset=t.offset(),f.containerPosition=t.position(),f.containerSize={height:t.innerHeight()-r[3],width:t.innerWidth()-r[1]},i=f.containerOffset,s=f.containerSize.height,o=f.containerSize.width,u=e.ui.hasScroll(p,"left")?p.scrollWidth:o,a=e.ui.hasScroll(p)?p.scrollHeight:s,f.parentData={element:p,left:i.left,top:i.top,width:u,height:a})},resize:function(t){var n,r,i,s,o=e(this).data("ui-resizable"),u=o.options,a=o.containerOffset,f=o.position,l=o._aspectRatio||t.shiftKey,c={top:0,left:0},h=o.containerElement;h[0]!==document&&/static/.test(h.css("position"))&&(c=a),f.left<(o._helper?a.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-a.left:o.position.left-c.left),l&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=u.helper?a.left:0),f.top<(o._helper?a.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-a.top:o.position.top),l&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?a.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,n=Math.abs((o._helper?o.offset.left-c.left:o.offset.left-c.left)+o.sizeDiff.width),r=Math.abs((o._helper?o.offset.top-c.top:o.offset.top-a.top)+o.sizeDiff.height),i=o.containerElement.get(0)===o.element.parent().get(0),s=/relative|absolute/.test(o.containerElement.css("position")),i&&s&&(n-=o.parentData.left),n+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-n,l&&(o.size.height=o.size.width/o.aspectRatio)),r+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-r,l&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.containerOffset,i=t.containerPosition,s=t.containerElement,o=e(t.helper),u=o.offset(),a=o.outerWidth()-t.sizeDiff.width,f=o.outerHeight()-t.sizeDiff.height;t._helper&&!n.animate&&/relative/.test(s.css("position"))&&e(this).css({left:u.left-i.left-r.left,width:a,height:f}),t._helper&&!n.animate&&/static/.test(s.css("position"))&&e(this).css({left:u.left-i.left-r.left,width:a,height:f})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).data("ui-resizable"),n=t.options,r=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof n.alsoResize=="object"&&!n.alsoResize.parentNode?n.alsoResize.length?(n.alsoResize=n.alsoResize[0],r(n.alsoResize)):e.each(n.alsoResize,function(e){r(e)}):r(n.alsoResize)},resize:function(t,n){var r=e(this).data("ui-resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("ui-resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:r.height,width:r.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof n.ghost=="string"?n.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).data("ui-resizable");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).data("ui-resizable");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.size,i=t.originalSize,s=t.originalPosition,o=t.axis,u=typeof n.grid=="number"?[n.grid,n.grid]:n.grid,a=u[0]||1,f=u[1]||1,l=Math.round((r.width-i.width)/a)*a,c=Math.round((r.height-i.height)/f)*f,h=i.width+l,p=i.height+c,d=n.maxWidth&&n.maxWidthh,g=n.minHeight&&n.minHeight>p;n.grid=u,m&&(h+=a),g&&(p+=f),d&&(h-=a),v&&(p-=f),/^(se|s|e)$/.test(o)?(t.size.width=h,t.size.height=p):/^(ne)$/.test(o)?(t.size.width=h,t.size.height=p,t.position.top=s.top-c):/^(sw)$/.test(o)?(t.size.width=h,t.size.height=p,t.position.left=s.left-l):(t.size.width=h,t.size.height=p,t.position.top=s.top-c,t.position.left=s.left-l)}})}(jQuery),function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.10.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,n=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(n.options.filter,n.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("
")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this,r=this.options;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().addBack().each(function(){var r,i=e.data(this,"selectable-item");if(i)return r=!t.metaKey&&!t.ctrlKey||!i.$element.hasClass("ui-selected"),i.$element.removeClass(r?"ui-unselecting":"ui-selected").addClass(r?"ui-selecting":"ui-unselecting"),i.unselecting=!r,i.selecting=r,i.selected=r,r?n._trigger("selecting",t,{selecting:i.element}):n._trigger("unselecting",t,{unselecting:i.element}),!1})},_mouseDrag:function(t){this.dragged=!0;if(this.options.disabled)return;var n,r=this,i=this.options,s=this.opos[0],o=this.opos[1],u=t.pageX,a=t.pageY;return s>u&&(n=u,u=s,s=n),o>a&&(n=a,a=o,o=n),this.helper.css({left:s,top:o,width:u-s,height:a-o}),this.selectees.each(function(){var n=e.data(this,"selectable-item"),f=!1;if(!n||n.element===r.element[0])return;i.tolerance==="touch"?f=!(n.left>u||n.righta||n.bottoms&&n.righto&&n.bottomt&&e *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=null,i=!1,s=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type==="static")return!1;this._refreshItems(t),e(t.target).parents().each(function(){if(e.data(this,s.widgetName+"-item")===s)return r=e(this),!1}),e.data(t.target,s.widgetName+"-item")===s&&(r=e(t.target));if(!r)return!1;if(this.options.handle&&!n){e(this.options.handle,r).find("*").addBack().each(function(){this===t.target&&(i=!0)});if(!i)return!1}return this.currentItem=r,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i,s=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,s.cursorAt&&this._adjustOffsetFromHelper(s.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),s.containment&&this._setContainment(),s.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",s.cursor)),s.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",s.opacity)),s.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",s.zIndex)),this.scrollParent[0]!==document&&this.scrollParent[0].tagName!=="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(i=this.containers.length-1;i>=0;i--)this.containers[i]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!s.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var n,r,i,s,o=this.options,u=!1;this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&this.scrollParent[0].tagName!=="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;n--){r=this.items[n],i=r.item[0],s=this._intersectsWithPointer(r);if(!s)continue;if(r.instance!==this.currentContainer)continue;if(i!==this.currentItem[0]&&this.placeholder[s===1?"next":"prev"]()[0]!==i&&!e.contains(this.placeholder[0],i)&&(this.options.type==="semi-dynamic"?!e.contains(this.element[0],i):!0)){this.direction=s===1?"down":"up";if(this.options.tolerance!=="pointer"&&!this._intersectsWithSides(r))break;this._rearrange(t,r),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper==="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!=="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+fs&&t+le[this.floating?"width":"height"]?c:s0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!==0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n,r,i,s,o=[],u=[],a=this._connectWith();if(a&&t)for(n=a.length-1;n>=0;n--){i=e(a[n]);for(r=i.length-1;r>=0;r--)s=e.data(i[r],this.widgetFullName),s&&s!==this&&!s.options.disabled&&u.push([e.isFunction(s.options.items)?s.options.items.call(s.element):e(s.options.items,s.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),s])}u.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(n=u.length-1;n>=0;n--)u[n][0].each(function(){o.push(this)});return e(o)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n=0;n--){i=e(h[n]);for(r=i.length-1;r>=0;r--)s=e.data(i[r],this.widgetFullName),s&&s!==this&&!s.options.disabled&&(c.push([e.isFunction(s.options.items)?s.options.items.call(s.element[0],t,{item:this.currentItem}):e(s.options.items,s.element),s]),this.containers.push(s))}for(n=c.length-1;n>=0;n--){o=c[n][1],u=c[n][0];for(r=0,f=u.length;r=0;n--){r=this.items[n];if(r.instance!==this.currentContainer&&this.currentContainer&&r.item[0]!==this.currentItem[0])continue;i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item,t||(r.width=i.outerWidth(),r.height=i.outerHeight()),s=i.offset(),r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(n=this.containers.length-1;n>=0;n--)s=this.containers[n].element.offset(),this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var n,r=t.options;if(!r.placeholder||r.placeholder.constructor===String)n=r.placeholder,r.placeholder={element:function(){var r=e(document.createElement(t.currentItem[0].nodeName)).addClass(n||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return n||(r.style.visibility="hidden"),r},update:function(e,i){if(n&&!r.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}};t.placeholder=e(r.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),r.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n,r,i,s,o,u,a,f,l,c=null,h=null;for(n=this.containers.length-1;n>=0;n--){if(e.contains(this.currentItem[0],this.containers[n].element[0]))continue;if(this._intersectsWith(this.containers[n].containerCache)){if(c&&e.contains(this.containers[n].element[0],c.element[0]))continue;c=this.containers[n],h=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",t,this._uiHash(this)),this.containers[n].containerCache.over=0)}if(!c)return;if(this.containers.length===1)this.containers[h]._trigger("over",t,this._uiHash(this)),this.containers[h].containerCache.over=1;else{i=1e4,s=null,o=this.containers[h].floating?"left":"top",u=this.containers[h].floating?"width":"height",a=this.positionAbs[o]+this.offset.click[o];for(r=this.items.length-1;r>=0;r--){if(!e.contains(this.containers[h].element[0],this.items[r].item[0]))continue;if(this.items[r].item[0]===this.currentItem[0])continue;f=this.items[r].item.offset()[o],l=!1,Math.abs(f-a)>Math.abs(f+this.items[r][u]-a)&&(l=!0,f+=this.items[r][u]),Math.abs(f-a)this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),i.grid&&(n=this.originalPageY+Math.round((o-this.originalPageY)/i.grid[1])*i.grid[1],o=this.containment?n-this.offset.click.top>=this.containment[1]&&n-this.offset.click.top<=this.containment[3]?n:n-this.offset.click.top>=this.containment[1]?n-i.grid[1]:n+i.grid[1]:n,r=this.originalPageX+Math.round((s-this.originalPageX)/i.grid[0])*i.grid[0],s=this.containment?r-this.offset.click.left>=this.containment[0]&&r-this.offset.click.left<=this.containment[2]?r:r-this.offset.click.left>=this.containment[0]?r-i.grid[0]:r+i.grid[0]:r)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition==="fixed"?-this.scrollParent.scrollTop():a?0:u.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition==="fixed"?-this.scrollParent.scrollLeft():a?0:u.scrollLeft())}},_rearrange:function(e,t,n,r){n?n[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],this.direction==="down"?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var i=this.counter;this._delay(function(){i===this.counter&&this.refreshPositions(!r)})},_clear:function(t,n){this.reverting=!1;var r,i=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]===this.currentItem[0]){for(r in this._storedCSS)if(this._storedCSS[r]==="auto"||this._storedCSS[r]==="static")this._storedCSS[r]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!n&&i.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!==this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!==this.currentItem.parent()[0])&&!n&&i.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(n||(i.push(function(e){this._trigger("remove",e,this._uiHash())}),i.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),i.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer))));for(r=this.containers.length-1;r>=0;r--)n||i.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[r])),this.containers[r].containerCache.over&&(i.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[r])),this.containers[r].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex==="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(r=0;re?0:r.max")[0],l,c=e.each;f.style.cssText="background-color:rgba(1,1,1,.5)",a.rgba=f.style.backgroundColor.indexOf("rgba")>-1,c(o,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),s.fn=e.extend(s.prototype,{parse:function(n,r,i,u){if(n===t)return this._rgba=[null,null,null,null],this;if(n.jquery||n.nodeType)n=e(n).css(r),r=t;var a=this,f=e.type(n),d=this._rgba=[];r!==t&&(n=[n,r,i,u],f="array");if(f==="string")return this.parse(p(n)||l._default);if(f==="array")return c(o.rgba.props,function(e,t){d[t.idx]=h(n[t.idx],t)}),this;if(f==="object")return n instanceof s?c(o,function(e,t){n[t.cache]&&(a[t.cache]=n[t.cache].slice())}):c(o,function(t,r){var i=r.cache;c(r.props,function(e,t){if(!a[i]&&r.to){if(e==="alpha"||n[e]==null)return;a[i]=r.to(a._rgba)}a[i][t.idx]=h(n[e],t,!0)}),a[i]&&e.inArray(null,a[i].slice(0,3))<0&&(a[i][3]=1,r.from&&(a._rgba=r.from(a[i])))}),this},is:function(e){var t=s(e),n=!0,r=this;return c(o,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],c(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return c(o,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=s(e),r=n._space(),i=o[r],a=this.alpha()===0?s("transparent"):this,f=a[i.cache]||i.to(a._rgba),l=f.slice();return n=n[i.cache],c(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],a=u[r.type]||{};if(o===null)return;s===null?l[i]=o:(a.mod&&(o-s>a.mod/2?s+=a.mod:s-o>a.mod/2&&(s-=a.mod)),l[i]=h((o-s)*t+s,r))}),this[r](l)},blend:function(t){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=s(t)._rgba;return s(e.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var t="rgba(",n=e.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),t="rgb("),t+n.join()+")"},toHslaString:function(){var t="hsla(",n=e.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),t="hsl("),t+n.join()+")"},toHexString:function(t){var n=this._rgba.slice(),r=n.pop();return t&&n.push(~~(r*255)),"#"+e.map(n,function(e){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),s.fn.parse.prototype=s.fn,o.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,u===0?c=0:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},o.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s;return[Math.round(d(o,s,t+1/3)*255),Math.round(d(o,s,t)*255),Math.round(d(o,s,t-1/3)*255),i]},c(o,function(n,i){var o=i.props,u=i.cache,a=i.to,f=i.from;s.fn[n]=function(n){a&&!this[u]&&(this[u]=a(this._rgba));if(n===t)return this[u].slice();var r,i=e.type(n),l=i==="array"||i==="object"?n:arguments,p=this[u].slice();return c(o,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=p[t.idx]),p[t.idx]=h(n,t)}),f?(r=s(f(p)),r[u]=p,r):s(p)},c(o,function(t,i){if(s.fn[t])return;s.fn[t]=function(s){var o=e.type(s),u=t==="alpha"?this._hsla?"hsla":"rgba":n,a=this[u](),f=a[i.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=e.type(s)),s==null&&i.empty?this:(o==="string"&&(l=r.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[i.idx]=s,this[u](a)))}})}),s.hook=function(t){var n=t.split(" ");c(n,function(t,n){e.cssHooks[n]={set:function(t,r){var i,o,u="";if(r!=="transparent"&&(e.type(r)!=="string"||(i=p(r)))){r=s(i||r);if(!a.rgba&&r._rgba[3]!==1){o=n==="backgroundColor"?t.parentNode:t;while((u===""||u==="transparent")&&o&&o.style)try{u=e.css(o,"backgroundColor"),o=o.parentNode}catch(f){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{t.style[n]=r}catch(f){}}},e.fx.step[n]=function(t){t.colorInit||(t.start=s(t.elem,n),t.end=s(t.end),t.colorInit=!0),e.cssHooks[n].set(t.elem,t.start.transition(t.end,t.pos))}})},s.hook(n),e.cssHooks.borderColor={expand:function(e){var t={};return c(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},l=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(t){var n,r,i=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,s={};if(i&&i.length&&i[0]&&i[i[0]]){r=i.length;while(r--)n=i[r],typeof i[n]=="string"&&(s[e.camelCase(n)]=i[n])}else for(n in i)typeof i[n]=="string"&&(s[n]=i[n]);return s}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").addBack():r;f=f.map(function(){var t=e(this);return{el:t,start:i(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=e.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return arguments.length>1?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass.apply(this,arguments)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function r(t,n,r,i){e.isPlainObject(t)&&(n=t,t=t.effect),t={effect:t},n==null&&(n={}),e.isFunction(n)&&(i=n,r=null,n={});if(typeof n=="number"||e.fx.speeds[n])i=r,r=n,n={};return e.isFunction(r)&&(i=r,r=null),n&&e.extend(t,n),r=r||n.duration,t.duration=e.fx.off?0:typeof r=="number"?r:r in e.fx.speeds?e.fx.speeds[r]:e.fx.speeds._default,t.complete=i||n.complete,t}function i(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]}e.extend(e.effects,{version:"1.10.1",save:function(e,t){for(var r=0;r").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(){function o(n){function u(){e.isFunction(i)&&i.call(r[0]),e.isFunction(n)&&n()}var r=e(this),i=t.complete,o=t.mode;(r.is(":hidden")?o==="hide":o==="show")?u():s.call(r[0],t,u)}var t=r.apply(this,arguments),n=t.mode,i=t.queue,s=e.effects.effect[t.effect];return e.fx.off||!s?n?this[n](t.duration,t.complete):this.each(function(){t.complete&&t.complete.call(this)}):i===!1?this.each(o):this.queue(i||"fx",o)},_show:e.fn.show,show:function(e){if(i(e))return this._show.apply(this,arguments);var t=r.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(i(e))return this._hide.apply(this,arguments);var t=r.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(i(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=r.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery),function(e,t){var n=0,r={},i={};r.height=r.paddingTop=r.paddingBottom=r.borderTopWidth=r.borderBottomWidth="hide",i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.10.1",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),!t.collapsible&&(t.active===!1||t.active==null)&&(t.active=0),this._processPanels(),t.active<0&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e(),content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this.options.heightStyle!=="content"&&e.css("height","")},_setOption:function(e,t){if(e==="active"){this._activate(t);return}e==="event"&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),e==="collapsible"&&!t&&this.options.active===!1&&this._activate(0),e==="icons"&&(this._destroyIcons(),t&&this._createIcons()),e==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)},_keydown:function(t){if(t.altKey||t.ctrlKey)return;var n=e.ui.keyCode,r=this.headers.length,i=this.headers.index(t.target),s=!1;switch(t.keyCode){case n.RIGHT:case n.DOWN:s=this.headers[(i+1)%r];break;case n.LEFT:case n.UP:s=this.headers[(i-1+r)%r];break;case n.SPACE:case n.ENTER:this._eventHandler(t);break;case n.HOME:s=this.headers[0];break;case n.END:s=this.headers[r-1]}s&&(e(t.target).attr("tabIndex",-1),e(s).attr("tabIndex",0),s.focus(),t.preventDefault())},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels();if(t.active===!1&&t.collapsible===!0||!this.headers.length)t.active=!1,this.active=e();t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var t,r=this.options,i=r.heightStyle,s=this.element.parent(),o=this.accordionId="ui-accordion-"+(this.element.attr("id")||++n);this.active=this._findActive(r.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(t){var n=e(this),r=n.attr("id"),i=n.next(),s=i.attr("id");r||(r=o+"-header-"+t,n.attr("id",r)),s||(s=o+"-panel-"+t,i.attr("id",s)),n.attr("aria-controls",s),i.attr("aria-labelledby",r)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(r.event),i==="fill"?(t=s.height(),this.element.siblings(":visible").each(function(){var n=e(this),r=n.css("position");if(r==="absolute"||r==="fixed")return;t-=n.outerHeight(!0)}),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):i==="auto"&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var n=this._findActive(t)[0];if(n===this.active[0])return;n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return typeof t=="number"?this.headers.eq(t):e()},_setupEvents:function(t){var n={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,n),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i[0]===r[0],o=s&&n.collapsible,u=o?e():i.next(),a=r.next(),f={oldHeader:r,oldPanel:a,newHeader:o?e():i,newPanel:u};t.preventDefault();if(s&&!n.collapsible||this._trigger("beforeActivate",t,f)===!1)return;n.active=o?!1:this.headers.index(i),this.active=s?e():i,this._toggle(f),r.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&r.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),s||(i.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),i.next().addClass("ui-accordion-content-active"))},_toggle:function(t){var n=t.newPanel,r=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=r,this.options.animate?this._animate(n,r,t):(r.hide(),n.show(),this._toggleComplete(t)),r.attr({"aria-expanded":"false","aria-hidden":"true"}),r.prev().attr("aria-selected","false"),n.length&&r.length?r.prev().attr("tabIndex",-1):n.length&&this.headers.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),n.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,n){var s,o,u,a=this,f=0,l=e.length&&(!t.length||e.index()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,n,r,i=this.element[0].nodeName.toLowerCase(),s=i==="textarea",o=i==="input";this.isMultiLine=s?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[s||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(i){if(this.element.prop("readOnly")){t=!0,r=!0,n=!0;return}t=!1,r=!1,n=!1;var s=e.ui.keyCode;switch(i.keyCode){case s.PAGE_UP:t=!0,this._move("previousPage",i);break;case s.PAGE_DOWN:t=!0,this._move("nextPage",i);break;case s.UP:t=!0,this._keyEvent("previous",i);break;case s.DOWN:t=!0,this._keyEvent("next",i);break;case s.ENTER:case s.NUMPAD_ENTER:this.menu.active&&(t=!0,i.preventDefault(),this.menu.select(i));break;case s.TAB:this.menu.active&&this.menu.select(i);break;case s.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(i),i.preventDefault());break;default:n=!0,this._searchTimeout(i)}},keypress:function(r){if(t){t=!1,r.preventDefault();return}if(n)return;var i=e.ui.keyCode;switch(r.keyCode){case i.PAGE_UP:this._move("previousPage",r);break;case i.PAGE_DOWN:this._move("nextPage",r);break;case i.UP:this._keyEvent("previous",r);break;case i.DOWN:this._keyEvent("next",r)}},input:function(e){if(r){r=!1,e.preventDefault();return}this._searchTimeout(e)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching),this.close(e),this._change(e)}}),this._initSource(),this.menu=e("