ipysketch-lite 0.0.5__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ipysketch_lite/__init__.py +5 -0
- ipysketch_lite/sketch.py +68 -0
- ipysketch_lite/template.py +190 -0
- ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/install.json +6 -0
- ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/package.json +192 -0
- ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/509.7b1e4dfc9bd86aa468d3.js +1 -0
- ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/728.da2a92e3613452e9fbe1.js +1 -0
- ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/remoteEntry.1e3a55bd0fc3134d9143.js +1 -0
- ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/style.js +4 -0
- ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/third-party-licenses.json +16 -0
- ipysketch_lite-0.0.5.dist-info/METADATA +59 -0
- ipysketch_lite-0.0.5.dist-info/RECORD +14 -0
- ipysketch_lite-0.0.5.dist-info/WHEEL +5 -0
- ipysketch_lite-0.0.5.dist-info/licenses/LICENSE +1 -0
ipysketch_lite/sketch.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import threading
|
|
3
|
+
import base64
|
|
4
|
+
import io
|
|
5
|
+
|
|
6
|
+
from IPython.display import HTML, display
|
|
7
|
+
from IPython.utils import path
|
|
8
|
+
|
|
9
|
+
from .template import template
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
import numpy as np
|
|
13
|
+
from PIL import Image
|
|
14
|
+
|
|
15
|
+
PIL_INSTALLED = True
|
|
16
|
+
except ImportError:
|
|
17
|
+
PIL_INSTALLED = False
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Sketch:
|
|
21
|
+
"""
|
|
22
|
+
Sketch class to create a sketch instance
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
data: str
|
|
26
|
+
|
|
27
|
+
def __init__(self, width: int = 400, height: int = 300):
|
|
28
|
+
self.data = ""
|
|
29
|
+
metadata = {
|
|
30
|
+
"{width}": width,
|
|
31
|
+
"{height}": height,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
sketch_template = template
|
|
35
|
+
for key, value in metadata.items():
|
|
36
|
+
sketch_template = sketch_template.replace(key, str(value))
|
|
37
|
+
|
|
38
|
+
display(HTML(sketch_template))
|
|
39
|
+
|
|
40
|
+
# run this in a separate thread
|
|
41
|
+
thread = threading.Thread(target=self.run_async)
|
|
42
|
+
thread.start()
|
|
43
|
+
|
|
44
|
+
def run_async(self):
|
|
45
|
+
asyncio.run(self.poll_message_contents())
|
|
46
|
+
|
|
47
|
+
async def poll_message_contents(self):
|
|
48
|
+
while True:
|
|
49
|
+
try:
|
|
50
|
+
message_path = path.filefind(".message.txt")
|
|
51
|
+
print(message_path)
|
|
52
|
+
if message_path:
|
|
53
|
+
with open(message_path, "r") as f:
|
|
54
|
+
self.data = f.read()
|
|
55
|
+
except Exception as e:
|
|
56
|
+
pass
|
|
57
|
+
await asyncio.sleep(1) # sleep for 1 second before next poll
|
|
58
|
+
|
|
59
|
+
def get_output(self) -> str:
|
|
60
|
+
return self.data
|
|
61
|
+
|
|
62
|
+
def get_output_array(self):
|
|
63
|
+
if PIL_INSTALLED:
|
|
64
|
+
image_data = self.data.split(",")[1]
|
|
65
|
+
image = Image.open(io.BytesIO(base64.b64decode(image_data)))
|
|
66
|
+
return np.array(image)
|
|
67
|
+
else:
|
|
68
|
+
raise ImportError("PIL (Pillow) and NumPy are required to use this method.")
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
template = """<style>
|
|
2
|
+
#toggleFill {
|
|
3
|
+
background-color: #f0f0f0;
|
|
4
|
+
border: 1px solid #999999;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
#toggleFill.active {
|
|
8
|
+
background-color: #ffffff;
|
|
9
|
+
border: 1px solid #000000;
|
|
10
|
+
}
|
|
11
|
+
</style>
|
|
12
|
+
<canvas
|
|
13
|
+
id="canvas"
|
|
14
|
+
width="{width}"
|
|
15
|
+
height="{height}"
|
|
16
|
+
style="border: 2px solid black"
|
|
17
|
+
></canvas>
|
|
18
|
+
<button id="toggleFill" onclick="toggleFill()">bucket</button>
|
|
19
|
+
<button onclick="clearCanvas()">clear</button>
|
|
20
|
+
<input id="color" type="color" value="#000000" />
|
|
21
|
+
<script>
|
|
22
|
+
var canvas = document.getElementById("canvas");
|
|
23
|
+
var colorInput = document.getElementById("color");
|
|
24
|
+
var toggleFillButton = document.getElementById("toggleFill");
|
|
25
|
+
var ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
26
|
+
ctx.lineWidth = 4;
|
|
27
|
+
ctx.lineJoin = "round";
|
|
28
|
+
var drawing = false;
|
|
29
|
+
var mouse = { x: 0, y: 0 };
|
|
30
|
+
var fillMode = false;
|
|
31
|
+
|
|
32
|
+
function canvasUpload() {
|
|
33
|
+
window.sendMessage(canvas.toDataURL());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
canvasUpload();
|
|
37
|
+
|
|
38
|
+
function toggleFill() {
|
|
39
|
+
fillMode = !fillMode;
|
|
40
|
+
toggleFillButton.classList.toggle("active", fillMode);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function hexToRgb(hex) {
|
|
44
|
+
return {
|
|
45
|
+
r: parseInt(hex.substring(1, 3), 16),
|
|
46
|
+
g: parseInt(hex.substring(3, 5), 16),
|
|
47
|
+
b: parseInt(hex.substring(5, 7), 16),
|
|
48
|
+
a: 255,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
canvas.addEventListener("mousedown", (e) => {
|
|
53
|
+
if (fillMode) {
|
|
54
|
+
floodFill(hexToRgb(colorInput.value), e.offsetX, e.offsetY);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
mouse = { x: e.offsetX, y: e.offsetY };
|
|
59
|
+
drawing = true;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
canvas.addEventListener("mousemove", (e) => {
|
|
63
|
+
if (drawing) {
|
|
64
|
+
drawLine(ctx, mouse.x, mouse.y, e.offsetX, e.offsetY);
|
|
65
|
+
mouse = { x: e.offsetX, y: e.offsetY };
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
canvas.addEventListener("mouseup", (e) => {
|
|
70
|
+
if (drawing) {
|
|
71
|
+
drawLine(ctx, mouse.x, mouse.y, e.offsetX, e.offsetY);
|
|
72
|
+
drawing = false;
|
|
73
|
+
canvasUpload();
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
function drawLine(context, x1, y1, x2, y2) {
|
|
78
|
+
ctx.strokeStyle = colorInput.value;
|
|
79
|
+
ctx.beginPath();
|
|
80
|
+
ctx.moveTo(x1, y1);
|
|
81
|
+
ctx.lineTo(x2, y2);
|
|
82
|
+
ctx.closePath();
|
|
83
|
+
ctx.stroke();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function clearCanvas() {
|
|
87
|
+
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function floodFill(color, x, y) {
|
|
91
|
+
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
92
|
+
const { width, height, data } = imgData;
|
|
93
|
+
if (pixelColMatch(x, y, color, data, width)) return;
|
|
94
|
+
|
|
95
|
+
const stack = [[x, y]];
|
|
96
|
+
let baseIdx = (width * y + x) * 4;
|
|
97
|
+
const oColor = {
|
|
98
|
+
r: data[baseIdx],
|
|
99
|
+
g: data[baseIdx + 1],
|
|
100
|
+
b: data[baseIdx + 2],
|
|
101
|
+
a: data[baseIdx + 3],
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
while (stack.length) {
|
|
105
|
+
var [cx, cy] = stack.pop();
|
|
106
|
+
const move = (dx, dy) => {
|
|
107
|
+
let nx = cx + dx;
|
|
108
|
+
let ny = cy + dy;
|
|
109
|
+
while (
|
|
110
|
+
ny >= 0 &&
|
|
111
|
+
ny < height &&
|
|
112
|
+
pixelColMatch(nx, ny, oColor, data, width)
|
|
113
|
+
) {
|
|
114
|
+
setPixelCol(nx, ny, color, data, width);
|
|
115
|
+
stack.push([nx, ny]);
|
|
116
|
+
ny += dy;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
move(0, 1);
|
|
120
|
+
move(0, -1);
|
|
121
|
+
move(-1, 0);
|
|
122
|
+
move(1, 0);
|
|
123
|
+
}
|
|
124
|
+
ctx.putImageData(imgData, 0, 0);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function pixelColMatch(x, y, color, data, width) {
|
|
128
|
+
var baseIdx = (width * y + x) * 4;
|
|
129
|
+
return (
|
|
130
|
+
data[baseIdx] === color.r &&
|
|
131
|
+
data[baseIdx + 1] === color.g &&
|
|
132
|
+
data[baseIdx + 2] === color.b &&
|
|
133
|
+
data[baseIdx + 3] === color.a
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function setPixelCol(x, y, color, data, width) {
|
|
138
|
+
var baseIdx = (width * y + x) * 4;
|
|
139
|
+
data[baseIdx] = color.r & 0xff;
|
|
140
|
+
data[baseIdx + 1] = color.g & 0xff;
|
|
141
|
+
data[baseIdx + 2] = color.b & 0xff;
|
|
142
|
+
data[baseIdx + 3] = color.a & 0xff;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
var rect = canvas.getBoundingClientRect();
|
|
146
|
+
var offset = { x: rect.left, y: rect.top };
|
|
147
|
+
var touches = [];
|
|
148
|
+
|
|
149
|
+
canvas.addEventListener("touchstart", (e) => {
|
|
150
|
+
e.preventDefault();
|
|
151
|
+
rect = canvas.getBoundingClientRect();
|
|
152
|
+
offset = { x: rect.left, y: rect.top };
|
|
153
|
+
touches = Array.from(e.touches);
|
|
154
|
+
|
|
155
|
+
if (fillMode) {
|
|
156
|
+
var x = Math.floor(touches[0].clientX - offset.x);
|
|
157
|
+
var y = Math.floor(touches[0].clientY - offset.y);
|
|
158
|
+
floodFill(hexToRgb(colorInput.value), x, y);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
canvas.addEventListener("touchend", (e) => {
|
|
163
|
+
canvasUpload();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
canvas.addEventListener("touchmove", (e) => {
|
|
167
|
+
if (fillMode) return;
|
|
168
|
+
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
rect = canvas.getBoundingClientRect();
|
|
171
|
+
offset = { x: rect.left, y: rect.top };
|
|
172
|
+
for (var i = 0; i < e.changedTouches.length; i++) {
|
|
173
|
+
var touch = e.changedTouches[i];
|
|
174
|
+
var previousTouch = touches.find(
|
|
175
|
+
(t) => t.identifier === touch.identifier,
|
|
176
|
+
);
|
|
177
|
+
if (previousTouch) {
|
|
178
|
+
drawLine(
|
|
179
|
+
ctx,
|
|
180
|
+
previousTouch.clientX - offset.x,
|
|
181
|
+
previousTouch.clientY - offset.y,
|
|
182
|
+
touch.clientX - offset.x,
|
|
183
|
+
touch.clientY - offset.y,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
touches.splice(i, 1, touch);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
</script>
|
|
190
|
+
"""
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ipysketch_lite",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A JupyterLab extension.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"jupyter",
|
|
7
|
+
"jupyterlab",
|
|
8
|
+
"jupyterlab-extension"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "/issues"
|
|
13
|
+
},
|
|
14
|
+
"license": "BSD-3-Clause",
|
|
15
|
+
"author": "Matthew Taylor",
|
|
16
|
+
"files": [
|
|
17
|
+
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
|
|
18
|
+
"style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
|
|
19
|
+
"src/**/*.{ts,tsx}"
|
|
20
|
+
],
|
|
21
|
+
"main": "lib/index.js",
|
|
22
|
+
"types": "lib/index.d.ts",
|
|
23
|
+
"style": "style/index.css",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": ".git"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "jlpm build:lib && jlpm build:labextension:dev",
|
|
30
|
+
"build:prod": "jlpm clean && jlpm build:lib:prod && jlpm build:labextension",
|
|
31
|
+
"build:labextension": "jupyter labextension build .",
|
|
32
|
+
"build:labextension:dev": "jupyter labextension build --development True .",
|
|
33
|
+
"build:lib": "tsc --sourceMap",
|
|
34
|
+
"build:lib:prod": "tsc",
|
|
35
|
+
"clean": "jlpm clean:lib",
|
|
36
|
+
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
|
|
37
|
+
"clean:lintcache": "rimraf .eslintcache .stylelintcache",
|
|
38
|
+
"clean:labextension": "rimraf ipysketch_lite/labextension",
|
|
39
|
+
"clean:all": "jlpm clean:lib && jlpm clean:labextension && jlpm clean:lintcache",
|
|
40
|
+
"eslint": "jlpm eslint:check --fix",
|
|
41
|
+
"eslint:check": "eslint . --cache --ext .ts,.tsx",
|
|
42
|
+
"install:extension": "jlpm build",
|
|
43
|
+
"lint": "jlpm stylelint && jlpm prettier && jlpm eslint",
|
|
44
|
+
"lint:check": "jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check",
|
|
45
|
+
"prettier": "jlpm prettier:base --write --list-different",
|
|
46
|
+
"prettier:base": "prettier \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
|
|
47
|
+
"prettier:check": "jlpm prettier:base --check",
|
|
48
|
+
"stylelint": "jlpm stylelint:check --fix",
|
|
49
|
+
"stylelint:check": "stylelint --cache \"style/**/*.css\"",
|
|
50
|
+
"watch": "run-p watch:src watch:labextension",
|
|
51
|
+
"watch:src": "tsc -w --sourceMap",
|
|
52
|
+
"watch:labextension": "jupyter labextension watch ."
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@jupyterlab/application": "^4.2.4",
|
|
56
|
+
"@jupyterlab/apputils": "^4.3.4",
|
|
57
|
+
"@jupyterlab/services": "^7.2.4",
|
|
58
|
+
"@lumino/widgets": "^2.5.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@jupyterlab/builder": "^4.0.0",
|
|
62
|
+
"@types/json-schema": "^7.0.11",
|
|
63
|
+
"@types/react": "^18.0.26",
|
|
64
|
+
"@types/react-addons-linked-state-mixin": "^0.14.22",
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^6.1.0",
|
|
66
|
+
"@typescript-eslint/parser": "^6.1.0",
|
|
67
|
+
"css-loader": "^6.7.1",
|
|
68
|
+
"eslint": "^8.36.0",
|
|
69
|
+
"eslint-config-prettier": "^8.8.0",
|
|
70
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
71
|
+
"npm-run-all": "^4.1.5",
|
|
72
|
+
"prettier": "^3.0.0",
|
|
73
|
+
"rimraf": "^5.0.1",
|
|
74
|
+
"source-map-loader": "^1.0.2",
|
|
75
|
+
"style-loader": "^3.3.1",
|
|
76
|
+
"stylelint": "^15.10.1",
|
|
77
|
+
"stylelint-config-recommended": "^13.0.0",
|
|
78
|
+
"stylelint-config-standard": "^34.0.0",
|
|
79
|
+
"stylelint-csstree-validator": "^3.0.0",
|
|
80
|
+
"stylelint-prettier": "^4.0.0",
|
|
81
|
+
"typescript": "~5.0.2",
|
|
82
|
+
"yjs": "^13.5.0"
|
|
83
|
+
},
|
|
84
|
+
"sideEffects": [
|
|
85
|
+
"style/*.css",
|
|
86
|
+
"style/index.js"
|
|
87
|
+
],
|
|
88
|
+
"styleModule": "style/index.js",
|
|
89
|
+
"publishConfig": {
|
|
90
|
+
"access": "public"
|
|
91
|
+
},
|
|
92
|
+
"jupyterlab": {
|
|
93
|
+
"extension": true,
|
|
94
|
+
"outputDir": "ipysketch_lite/labextension",
|
|
95
|
+
"_build": {
|
|
96
|
+
"load": "static/remoteEntry.1e3a55bd0fc3134d9143.js",
|
|
97
|
+
"extension": "./extension",
|
|
98
|
+
"style": "./style"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"eslintIgnore": [
|
|
102
|
+
"node_modules",
|
|
103
|
+
"dist",
|
|
104
|
+
"coverage",
|
|
105
|
+
"**/*.d.ts"
|
|
106
|
+
],
|
|
107
|
+
"eslintConfig": {
|
|
108
|
+
"extends": [
|
|
109
|
+
"eslint:recommended",
|
|
110
|
+
"plugin:@typescript-eslint/eslint-recommended",
|
|
111
|
+
"plugin:@typescript-eslint/recommended",
|
|
112
|
+
"plugin:prettier/recommended"
|
|
113
|
+
],
|
|
114
|
+
"parser": "@typescript-eslint/parser",
|
|
115
|
+
"parserOptions": {
|
|
116
|
+
"project": "tsconfig.json",
|
|
117
|
+
"sourceType": "module"
|
|
118
|
+
},
|
|
119
|
+
"plugins": [
|
|
120
|
+
"@typescript-eslint"
|
|
121
|
+
],
|
|
122
|
+
"rules": {
|
|
123
|
+
"@typescript-eslint/naming-convention": [
|
|
124
|
+
"error",
|
|
125
|
+
{
|
|
126
|
+
"selector": "interface",
|
|
127
|
+
"format": [
|
|
128
|
+
"PascalCase"
|
|
129
|
+
],
|
|
130
|
+
"custom": {
|
|
131
|
+
"regex": "^I[A-Z]",
|
|
132
|
+
"match": true
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"@typescript-eslint/no-unused-vars": [
|
|
137
|
+
"warn",
|
|
138
|
+
{
|
|
139
|
+
"args": "none"
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
143
|
+
"@typescript-eslint/no-namespace": "off",
|
|
144
|
+
"@typescript-eslint/no-use-before-define": "off",
|
|
145
|
+
"@typescript-eslint/quotes": [
|
|
146
|
+
"error",
|
|
147
|
+
"single",
|
|
148
|
+
{
|
|
149
|
+
"avoidEscape": true,
|
|
150
|
+
"allowTemplateLiterals": false
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"curly": [
|
|
154
|
+
"error",
|
|
155
|
+
"all"
|
|
156
|
+
],
|
|
157
|
+
"eqeqeq": "error",
|
|
158
|
+
"prefer-arrow-callback": "error"
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"prettier": {
|
|
162
|
+
"singleQuote": true,
|
|
163
|
+
"trailingComma": "none",
|
|
164
|
+
"arrowParens": "avoid",
|
|
165
|
+
"endOfLine": "auto",
|
|
166
|
+
"overrides": [
|
|
167
|
+
{
|
|
168
|
+
"files": "package.json",
|
|
169
|
+
"options": {
|
|
170
|
+
"tabWidth": 4
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
"stylelint": {
|
|
176
|
+
"extends": [
|
|
177
|
+
"stylelint-config-recommended",
|
|
178
|
+
"stylelint-config-standard",
|
|
179
|
+
"stylelint-prettier/recommended"
|
|
180
|
+
],
|
|
181
|
+
"plugins": [
|
|
182
|
+
"stylelint-csstree-validator"
|
|
183
|
+
],
|
|
184
|
+
"rules": {
|
|
185
|
+
"csstree/validator": true,
|
|
186
|
+
"property-no-vendor-prefix": null,
|
|
187
|
+
"selector-class-pattern": "^([a-z][A-z\\d]*)(-[A-z\\d]+)*$",
|
|
188
|
+
"selector-no-vendor-prefix": null,
|
|
189
|
+
"value-no-vendor-prefix": null
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunkipysketch_lite=self.webpackChunkipysketch_lite||[]).push([[509],{509:(e,s,t)=>{t.r(s),t.d(s,{default:()=>n});const n={id:"ipysketch:plugin",autoStart:!0,activate:e=>{console.log("ipysketch plugin activated"),console.log(e.serviceManager.contents),window.sendMessage=async s=>{console.log("sending message"),await e.serviceManager.contents.save(".message.txt",{type:"file",content:s})}}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunkipysketch_lite=self.webpackChunkipysketch_lite||[]).push([[728],{475:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(601),o=n.n(r),a=n(314),i=n.n(a)()(o());i.push([e.id,"/*\n See the JupyterLab Developer Guide for useful CSS Patterns:\n\n https://jupyterlab.readthedocs.io/en/stable/developer/css.html\n*/\n",""]);const s=i},314:e=>{e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n="",r=void 0!==t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),r&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),r&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n})).join("")},t.i=function(e,n,r,o,a){"string"==typeof e&&(e=[[null,e,void 0]]);var i={};if(r)for(var s=0;s<this.length;s++){var c=this[s][0];null!=c&&(i[c]=!0)}for(var u=0;u<e.length;u++){var l=[].concat(e[u]);r&&i[l[0]]||(void 0!==a&&(void 0===l[5]||(l[1]="@layer".concat(l[5].length>0?" ".concat(l[5]):""," {").concat(l[1],"}")),l[5]=a),n&&(l[2]?(l[1]="@media ".concat(l[2]," {").concat(l[1],"}"),l[2]=n):l[2]=n),o&&(l[4]?(l[1]="@supports (".concat(l[4],") {").concat(l[1],"}"),l[4]=o):l[4]="".concat(o)),t.push(l))}},t}},601:e=>{e.exports=function(e){return e[1]}},72:e=>{var t=[];function n(e){for(var n=-1,r=0;r<t.length;r++)if(t[r].identifier===e){n=r;break}return n}function r(e,r){for(var a={},i=[],s=0;s<e.length;s++){var c=e[s],u=r.base?c[0]+r.base:c[0],l=a[u]||0,p="".concat(u," ").concat(l);a[u]=l+1;var f=n(p),d={css:c[1],media:c[2],sourceMap:c[3],supports:c[4],layer:c[5]};if(-1!==f)t[f].references++,t[f].updater(d);else{var v=o(d,r);r.byIndex=s,t.splice(s,0,{identifier:p,updater:v,references:1})}i.push(p)}return i}function o(e,t){var n=t.domAPI(t);return n.update(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap&&t.supports===e.supports&&t.layer===e.layer)return;n.update(e=t)}else n.remove()}}e.exports=function(e,o){var a=r(e=e||[],o=o||{});return function(e){e=e||[];for(var i=0;i<a.length;i++){var s=n(a[i]);t[s].references--}for(var c=r(e,o),u=0;u<a.length;u++){var l=n(a[u]);0===t[l].references&&(t[l].updater(),t.splice(l,1))}a=c}}},659:e=>{var t={};e.exports=function(e,n){var r=function(e){if(void 0===t[e]){var n=document.querySelector(e);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}t[e]=n}return t[e]}(e);if(!r)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");r.appendChild(n)}},540:e=>{e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},56:(e,t,n)=>{e.exports=function(e){var t=n.nc;t&&e.setAttribute("nonce",t)}},825:e=>{e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=e.insertStyleElement(e);return{update:function(n){!function(e,t,n){var r="";n.supports&&(r+="@supports (".concat(n.supports,") {")),n.media&&(r+="@media ".concat(n.media," {"));var o=void 0!==n.layer;o&&(r+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),r+=n.css,o&&(r+="}"),n.media&&(r+="}"),n.supports&&(r+="}");var a=n.sourceMap;a&&"undefined"!=typeof btoa&&(r+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),t.styleTagTransform(r,e,t.options)}(t,e,n)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},113:e=>{e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},728:(e,t,n)=>{var r=n(72),o=n.n(r),a=n(825),i=n.n(a),s=n(659),c=n.n(s),u=n(56),l=n.n(u),p=n(540),f=n.n(p),d=n(113),v=n.n(d),h=n(475),m={};m.styleTagTransform=v(),m.setAttributes=l(),m.insert=c().bind(null,"head"),m.domAPI=i(),m.insertStyleElement=f(),o()(h.A,m),h.A&&h.A.locals&&h.A.locals}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var _JUPYTERLAB;(()=>{"use strict";var e,t,r={931:(e,t,r)=>{var i={"./index":()=>r.e(509).then((()=>()=>r(509))),"./extension":()=>r.e(509).then((()=>()=>r(509))),"./style":()=>r.e(728).then((()=>()=>r(728)))},o=(e,t)=>(r.R=t,t=r.o(i,e)?i[e]():Promise.resolve().then((()=>{throw new Error('Module "'+e+'" does not exist in container.')})),r.R=void 0,t),a=(e,t)=>{if(r.S){var i="default",o=r.S[i];if(o&&o!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return r.S[i]=e,r.I(i,t)}};r.d(t,{get:()=>o,init:()=>a})}},i={};function o(e){var t=i[e];if(void 0!==t)return t.exports;var a=i[e]={id:e,exports:{}};return r[e](a,a.exports,o),a.exports}o.m=r,o.c=i,o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var r in t)o.o(t,r)&&!o.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce(((t,r)=>(o.f[r](e,t),t)),[])),o.u=e=>e+"."+{509:"7b1e4dfc9bd86aa468d3",728:"da2a92e3613452e9fbe1"}[e]+".js?v="+{509:"7b1e4dfc9bd86aa468d3",728:"da2a92e3613452e9fbe1"}[e],o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="ipysketch_lite:",o.l=(r,i,a,n)=>{if(e[r])e[r].push(i);else{var l,s;if(void 0!==a)for(var c=document.getElementsByTagName("script"),u=0;u<c.length;u++){var d=c[u];if(d.getAttribute("src")==r||d.getAttribute("data-webpack")==t+a){l=d;break}}l||(s=!0,(l=document.createElement("script")).charset="utf-8",l.timeout=120,o.nc&&l.setAttribute("nonce",o.nc),l.setAttribute("data-webpack",t+a),l.src=r),e[r]=[i];var p=(t,i)=>{l.onerror=l.onload=null,clearTimeout(f);var o=e[r];if(delete e[r],l.parentNode&&l.parentNode.removeChild(l),o&&o.forEach((e=>e(i))),t)return t(i)},f=setTimeout(p.bind(null,void 0,{type:"timeout",target:l}),12e4);l.onerror=p.bind(null,l.onerror),l.onload=p.bind(null,l.onload),s&&document.head.appendChild(l)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{o.S={};var e={},t={};o.I=(r,i)=>{i||(i=[]);var a=t[r];if(a||(a=t[r]={}),!(i.indexOf(a)>=0)){if(i.push(a),e[r])return e[r];o.o(o.S,r)||(o.S[r]={});var n=o.S[r],l="ipysketch_lite",s=[];return"default"===r&&((e,t,r,i)=>{var a=n[e]=n[e]||{},s=a[t];(!s||!s.loaded&&(1!=!s.eager?i:l>s.from))&&(a[t]={get:()=>o.e(509).then((()=>()=>o(509))),from:l,eager:!1})})("ipysketch_lite","0.1.0"),e[r]=s.length?Promise.all(s).then((()=>e[r]=1)):1}}})(),(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var t=o.g.document;if(!e&&t&&(t.currentScript&&(e=t.currentScript.src),!e)){var r=t.getElementsByTagName("script");if(r.length)for(var i=r.length-1;i>-1&&(!e||!/^http(s?):/.test(e));)e=r[i--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={420:0};o.f.j=(t,r)=>{var i=o.o(e,t)?e[t]:void 0;if(0!==i)if(i)r.push(i[2]);else{var a=new Promise(((r,o)=>i=e[t]=[r,o]));r.push(i[2]=a);var n=o.p+o.u(t),l=new Error;o.l(n,(r=>{if(o.o(e,t)&&(0!==(i=e[t])&&(e[t]=void 0),i)){var a=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;l.message="Loading chunk "+t+" failed.\n("+a+": "+n+")",l.name="ChunkLoadError",l.type=a,l.request=n,i[1](l)}}),"chunk-"+t,t)}};var t=(t,r)=>{var i,a,[n,l,s]=r,c=0;if(n.some((t=>0!==e[t]))){for(i in l)o.o(l,i)&&(o.m[i]=l[i]);s&&s(o)}for(t&&t(r);c<n.length;c++)a=n[c],o.o(e,a)&&e[a]&&e[a][0](),e[a]=0},r=self.webpackChunkipysketch_lite=self.webpackChunkipysketch_lite||[];r.forEach(t.bind(null,0)),r.push=t.bind(null,r.push.bind(r))})(),o.nc=void 0;var a=o(931);(_JUPYTERLAB=void 0===_JUPYTERLAB?{}:_JUPYTERLAB).ipysketch_lite=a})();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packages": [
|
|
3
|
+
{
|
|
4
|
+
"name": "css-loader",
|
|
5
|
+
"versionInfo": "6.11.0",
|
|
6
|
+
"licenseId": "MIT",
|
|
7
|
+
"extractedText": "Copyright JS Foundation and other contributors\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"name": "style-loader",
|
|
11
|
+
"versionInfo": "3.3.4",
|
|
12
|
+
"licenseId": "MIT",
|
|
13
|
+
"extractedText": "Copyright JS Foundation and other contributors\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: ipysketch-lite
|
|
3
|
+
Version: 0.0.5
|
|
4
|
+
Summary: Simple sketching tool for Jupyter notebooks
|
|
5
|
+
Project-URL: Homepage, https://github.com/MatthewAndreTaylor/ipysketch_lite
|
|
6
|
+
Author-email: Matthew Taylor <matthew.taylor.andre@gmail.com>
|
|
7
|
+
License: Copyright (c) 2024 Matthew Andre Taylor
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: canvas,drawing,jupyter,sketch
|
|
10
|
+
Provides-Extra: extras
|
|
11
|
+
Requires-Dist: numpy; extra == 'extras'
|
|
12
|
+
Requires-Dist: pillow; extra == 'extras'
|
|
13
|
+
Provides-Extra: test
|
|
14
|
+
Requires-Dist: matplotlib; extra == 'test'
|
|
15
|
+
Requires-Dist: numpy; extra == 'test'
|
|
16
|
+
Requires-Dist: pillow; extra == 'test'
|
|
17
|
+
Requires-Dist: torch; extra == 'test'
|
|
18
|
+
Requires-Dist: torchvision; extra == 'test'
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# ipysketch_lite
|
|
22
|
+
|
|
23
|
+
A lite sketching utility for python notebooks, no sockets or extra dependencies 🎨
|
|
24
|
+
|
|
25
|
+
(no extra widget code)
|
|
26
|
+
|
|
27
|
+
Make sketches right in your notebook then use the sketch in your python code.
|
|
28
|
+
|
|
29
|
+
Try yourself:
|
|
30
|
+
|
|
31
|
+
<a href="https://matthewandretaylor.github.io/ipysketch_lite/jupyterlite/lab/index.html">
|
|
32
|
+
<img alt="jupyterlite badge" src="https://jupyterlite.rtfd.io/en/latest/_static/badge.svg">
|
|
33
|
+
</a>
|
|
34
|
+
|
|
35
|
+
## Quickstart
|
|
36
|
+
|
|
37
|
+
Start drawing a quick sketch in your notebook like this
|
|
38
|
+
|
|
39
|
+
```py
|
|
40
|
+
from ipysketch_lite import Sketch
|
|
41
|
+
|
|
42
|
+
sketch = Sketch()
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then add a new cell to retrieve the sketch in python
|
|
46
|
+
|
|
47
|
+
```py
|
|
48
|
+
print(sketch.get_output())
|
|
49
|
+
|
|
50
|
+
import matplotlib.pyplot as plt
|
|
51
|
+
|
|
52
|
+
plt.imshow(sketch.get_output_array())
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
Sketches get updated in cells after draw updates
|
|
58
|
+
|
|
59
|
+
This means you can continue your sketch and get the new updated outputs
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
ipysketch_lite/__init__.py,sha256=ozP-1j99UoaPf_3SZx5UNbFU8vmMiO_Ix1ciuLXIXwQ,127
|
|
2
|
+
ipysketch_lite/sketch.py,sha256=2Vh3ppp8UyKINGBmNRteUpjXCcgCtCkR95P5RKYZxiw,1774
|
|
3
|
+
ipysketch_lite/template.py,sha256=Z5Zel6ZzZWl73apjMRhe7AlwaE6V6FSXVBtSY8dBQ88,4847
|
|
4
|
+
ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/package.json,sha256=CMcPXv0BReNAGed_lz7NqimNkgIGABATrIk04_BeFgE,5454
|
|
5
|
+
ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/509.7b1e4dfc9bd86aa468d3.js,sha256=ex5N_JvYaqRo0966DbphJKhD1phjikrnn7eIGi8auAg,422
|
|
6
|
+
ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/728.da2a92e3613452e9fbe1.js,sha256=2iqS42E0Uun74UeTY9twfH_a4__anWJik6j3SNrDC4U,3999
|
|
7
|
+
ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/remoteEntry.1e3a55bd0fc3134d9143.js,sha256=HjpVvQ_DE02RQ7y1RFiu6US7sE6Br5SFeI3URm70CYw,3920
|
|
8
|
+
ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/style.js,sha256=iOarCbuXAXkY-BeISuRVdSx3Ht1v-TXfEhBHjcEhwWU,157
|
|
9
|
+
ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/static/third-party-licenses.json,sha256=W6N2sSD7tQihMqQk64F9xMd1Flfr2KO97esAiHUOYdM,2453
|
|
10
|
+
ipysketch_lite-0.0.5.data/data/share/jupyter/labextensions/ipysketch_lite/install.json,sha256=pJS85xD1wnABg2ce5XgEKiaWWHm2HF7Z8tWHAHbrv8g,191
|
|
11
|
+
ipysketch_lite-0.0.5.dist-info/METADATA,sha256=rR1N8wGjYhC-ixhap-uj48aoNofV8zMWeZHmvITfutE,1673
|
|
12
|
+
ipysketch_lite-0.0.5.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
|
|
13
|
+
ipysketch_lite-0.0.5.dist-info/licenses/LICENSE,sha256=-guCcX4glX_hMB9LpAtB_If_h0xpXsm0wvc55655x6M,39
|
|
14
|
+
ipysketch_lite-0.0.5.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Copyright (c) 2024 Matthew Andre Taylor
|