first commit
commit
646e3d51a3
@ -0,0 +1,4 @@
|
|||||||
|
db/
|
||||||
|
**/__pycache__/
|
||||||
|
media/
|
||||||
|
venv/
|
@ -0,0 +1,27 @@
|
|||||||
|
How does 2bitcharactergenerator actually work?
|
||||||
|
|
||||||
|
Let's make all the canvas elements visible...
|
||||||
|
|
||||||
|
The stylesheet sets "image-rendering: pixelated" on the canvas element, which seems to be supported on contemporary Firefox + Chrome. The elements have width and height attributes set to 16, while their height in CSS is set to 64px producing a (pixelated) scaling up. However the actual size in the canvas coordinates remains unscaled.
|
||||||
|
|
||||||
|
This makes caption generation in the canvas tricky.
|
||||||
|
|
||||||
|
https://developer.mozilla.org/en-US/docs/Games/Techniques/Crisp_pixel_art_look
|
||||||
|
|
||||||
|
diggin into the history of workadventure
|
||||||
|
|
||||||
|
https://web.archive.org/web/20210623060444/https://thecodingmachine.io/energy-consumption-web-game-engine
|
||||||
|
|
||||||
|
https://medium.com/@michaelwesthadley/modular-game-worlds-in-phaser-3-tilemaps-1-958fc7e6bbd6
|
||||||
|
|
||||||
|
https://docs.phaser.io/api-documentation/class/tilemaps-tilemap
|
||||||
|
|
||||||
|
FOCUS
|
||||||
|
* CALL as good self-contained page.
|
||||||
|
* POST -> LINK to "visit (rp)guestbook"
|
||||||
|
* ANIMATION GENERATOR... (for mail/masto/IG)
|
||||||
|
|
||||||
|
"I want to be"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import Creature
|
||||||
|
|
||||||
|
admin.site.register(Creature)
|
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CallConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'call'
|
@ -0,0 +1,14 @@
|
|||||||
|
from django.forms import ModelForm
|
||||||
|
from call.models import Creature
|
||||||
|
|
||||||
|
|
||||||
|
class CreatureForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Creature
|
||||||
|
fields = ["image", "caption", "message"]
|
||||||
|
|
||||||
|
class CreatureFormNoImage(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Creature
|
||||||
|
fields = ["caption", "message"]
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-01-21 07:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Creature',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('image', models.ImageField(upload_to='creatures')),
|
||||||
|
('caption', models.CharField(max_length=255)),
|
||||||
|
('created', models.DateTimeField(auto_now_add=True, verbose_name='date created')),
|
||||||
|
('updated', models.DateTimeField(auto_now=True, verbose_name='date updated')),
|
||||||
|
('message', models.TextField(max_length=512)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-01-21 07:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('call', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='creature',
|
||||||
|
name='message',
|
||||||
|
field=models.TextField(blank=True, max_length=512),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,12 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Creature(models.Model):
|
||||||
|
image = models.ImageField(upload_to="creatures")
|
||||||
|
caption = models.CharField(max_length=255)
|
||||||
|
created = models.DateTimeField("date created", auto_now_add=True)
|
||||||
|
updated = models.DateTimeField("date updated", auto_now=True)
|
||||||
|
message = models.TextField(max_length=512, blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ["-created"]
|
@ -0,0 +1,395 @@
|
|||||||
|
var PARTS_MAX = {
|
||||||
|
eyes: 12,
|
||||||
|
mouth: 8,
|
||||||
|
ears: 6,
|
||||||
|
torso: 5,
|
||||||
|
hair: 22,
|
||||||
|
};
|
||||||
|
var gParts = {}
|
||||||
|
var gColor = 0;
|
||||||
|
var gColorMode = '012';
|
||||||
|
|
||||||
|
var showCanvas = document.getElementById('c');
|
||||||
|
|
||||||
|
var outCanvas = document.getElementById('outc');
|
||||||
|
outCanvas.width = 16 * 6;
|
||||||
|
outCanvas.height = 16 * 1;
|
||||||
|
|
||||||
|
|
||||||
|
var ctx = showCanvas.getContext('2d');
|
||||||
|
var outCtx = outCanvas.getContext('2d');
|
||||||
|
|
||||||
|
var outCanvas_gbs_s = document.getElementById("outc_gbs_s")
|
||||||
|
outCanvas_gbs_s.width = 48
|
||||||
|
outCanvas_gbs_s.height = 16
|
||||||
|
|
||||||
|
var outCanvas_gbs_a = document.getElementById("outc_gbs_a")
|
||||||
|
outCanvas_gbs_a.width = 96
|
||||||
|
outCanvas_gbs_a.height = 16
|
||||||
|
|
||||||
|
var outCtx_gbs_s = outCanvas_gbs_s.getContext('2d');
|
||||||
|
var outCtx_gbs_a = outCanvas_gbs_a.getContext('2d');
|
||||||
|
|
||||||
|
var a = function(n) {
|
||||||
|
return n
|
||||||
|
.split(',')
|
||||||
|
.map(function(k){ return { x: parseInt(k), f: !!k.match('f')} });
|
||||||
|
}
|
||||||
|
var ANIMS = {
|
||||||
|
stand: a("0"),
|
||||||
|
rotate: a("0,2f,1,2"),
|
||||||
|
run_front: a("0,3,0f,3f"),
|
||||||
|
run_back: a("1,4,1f,4f"),
|
||||||
|
run_left: a("2,5"),
|
||||||
|
run_right: a("2f,5f"),
|
||||||
|
}
|
||||||
|
var ANIM_NAMES = Object.keys(ANIMS);
|
||||||
|
var currentAnimName = "stand";
|
||||||
|
|
||||||
|
var gTextures = { loaded: 0, requested: 0 };
|
||||||
|
|
||||||
|
loadAllTextures();
|
||||||
|
|
||||||
|
var __appstarted = false;
|
||||||
|
function loadTexture(key) {
|
||||||
|
// var tex = new Image();
|
||||||
|
var tex = document.querySelector("#all_imgs").querySelector('#img_'+key);
|
||||||
|
|
||||||
|
// tex.src = "./" + key + ".png?v=" + Math.random();
|
||||||
|
gTextures.requested++;
|
||||||
|
gTextures[key] = tex;
|
||||||
|
|
||||||
|
var tex_onload = function() {
|
||||||
|
gTextures.loaded++;
|
||||||
|
if(gTextures.loaded === gTextures.requested){
|
||||||
|
if(__appstarted){
|
||||||
|
updateOutCanvas();
|
||||||
|
} else {
|
||||||
|
startApp();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.getElementById('loading').innerText =
|
||||||
|
"loading... " + gTextures.loaded + " / " + gTextures.requested;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex.complete) {
|
||||||
|
window.setTimeout(tex_onload, 10);
|
||||||
|
} else {
|
||||||
|
tex.onload = tex_onload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadAllTextures() {
|
||||||
|
loadTexture("hair");
|
||||||
|
loadTexture("base");
|
||||||
|
loadTexture("eyes");
|
||||||
|
loadTexture("mouth");
|
||||||
|
loadTexture("ears");
|
||||||
|
loadTexture("torso");
|
||||||
|
loadTexture("hands");
|
||||||
|
}
|
||||||
|
|
||||||
|
function startApp() {
|
||||||
|
__appstarted = true;
|
||||||
|
setupInput("eyes")
|
||||||
|
setupInput("mouth")
|
||||||
|
setupInput("ears")
|
||||||
|
setupInput("torso")
|
||||||
|
setupInput("hair")
|
||||||
|
setupColorInput();
|
||||||
|
setupColorMode();
|
||||||
|
|
||||||
|
updateOutCanvas();
|
||||||
|
updateAnimBtnText();
|
||||||
|
window.setInterval(animate, 16);
|
||||||
|
|
||||||
|
document.getElementById('loading').innerText = '';
|
||||||
|
document.getElementById('root').className = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate(){
|
||||||
|
ctx.clearRect(0, 0, 16, 16);
|
||||||
|
var t = Date.now ? Date.now() : +(new Date());
|
||||||
|
|
||||||
|
var nt = parseInt(t / 200)
|
||||||
|
var anim = ANIMS[currentAnimName];
|
||||||
|
var len = anim.length;
|
||||||
|
|
||||||
|
var findex = nt % len;
|
||||||
|
var frame = anim[findex];
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
if(frame.f){
|
||||||
|
ctx.translate(16, 0);
|
||||||
|
ctx.scale(-1, 1);
|
||||||
|
}
|
||||||
|
ctx.drawImage(outCanvas, frame.x * 16, 0, 16, 16, 0, 0, 16, 16);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var animbtn = document.getElementById('animbtn');
|
||||||
|
function updateAnimBtnText(){
|
||||||
|
animbtn.innerText = currentAnimName.replace("_", " ");
|
||||||
|
}
|
||||||
|
animbtn.onclick = function() {
|
||||||
|
var index = ANIM_NAMES.indexOf(currentAnimName);
|
||||||
|
currentAnimName = ANIM_NAMES[index + 1] || ANIM_NAMES[0];
|
||||||
|
updateAnimBtnText();
|
||||||
|
}
|
||||||
|
showCanvas.onclick = animbtn.onclick;
|
||||||
|
|
||||||
|
// var randomizebtn = document.getElementById('randomizebtn');
|
||||||
|
// randomizebtn.onclick = function() {
|
||||||
|
// var inputs = document.getElementById('inputs').querySelectorAll('input');
|
||||||
|
|
||||||
|
// for(var i=0; i<inputs.length; i++){
|
||||||
|
// var input = inputs[i];
|
||||||
|
|
||||||
|
// var key = input.id.replace("Input", "");
|
||||||
|
// var max = PARTS_MAX[key];
|
||||||
|
// var randval = Math.floor(Math.random() * (max + 1));
|
||||||
|
// input.value = randval;
|
||||||
|
// gParts[key] = randval;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// updateOutCanvas();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 13 * 9 * 7 * 6 * 23 = 113'022
|
||||||
|
|
||||||
|
var COLORS = [
|
||||||
|
["#000000", "#787878", "#e8e8e8", "#ffffff", "Basic"],
|
||||||
|
["#071821", "#86c06c", "#e0f8cf", "#65ff00", "GBS"],
|
||||||
|
["#7c3f58", "#eb6b6f", "#f9a875", "#fff6d3", "ICE CREAM GB PALETTE by Kerrie Lake"],
|
||||||
|
["#2d1b00", "#1e606e", "#5ab9a8", "#c4f0c2", "MIST GB PALETTE by Kerrie Lake"],
|
||||||
|
["#2c2137", "#764462", "#edb4a1", "#a96868", "RUSTIC GB PALETTE by Kerrie Lake"],
|
||||||
|
["#20283d", "#426e5d", "#e5b083", "#fbf7f3", "EN4 PALETTE by ENDESGA"],
|
||||||
|
["#4c1c2d", "#d23c4e", "#5fb1f5", "#eaf5fa", "GRAND DAD 4 PALETTE by Starlane"],
|
||||||
|
[ "#181010", "#84739c", "#f7b58c", "#ffefff", "POKEMON (SGB) PALETTE" ],
|
||||||
|
[ "#2b2b26", "#706b66", "#a89f94", "#e0dbcd", "GRAFXKID GAMEBOY POCKET (GRAY) PALETTE by GrafxKid" ],
|
||||||
|
[ "#000000", "#ff55ff", "#55ffff", "#ffffff", "CGA PALETTE 1 (HIGH) PALETTE" ],
|
||||||
|
[ "#243137", "#3f503f", "#768448", "#acb56b", "NINTENDO GAMEBOY (ARNE) PALETTE by Arne" ],
|
||||||
|
[ "#260016", "#ed008c", "#00bff3", "#daf3ec", "JB4 PALETTE by Haretro for his game Jet Boy" ],
|
||||||
|
[ "#253b46", "#18865f", "#61d162", "#ebe7ad", "SWEET GUARANÁ PALETTE by MadPezkoh" ],
|
||||||
|
[ "#4c625a", "#7b9278", "#abc396", "#dbf4b4", "GRAFXKID GAMEBOY POCKET (GREEN) PALETTE by GrafxKid" ],
|
||||||
|
];
|
||||||
|
|
||||||
|
function drawPart(key, forceY, forceFrame){
|
||||||
|
var y = gParts[key] == null ? forceY : gParts[key]; // 0's falsy
|
||||||
|
if(y == null){ return }
|
||||||
|
var w = 16 * 6;
|
||||||
|
var h = 16;
|
||||||
|
|
||||||
|
|
||||||
|
if(forceFrame || forceFrame === 0){
|
||||||
|
outCtx.drawImage(gTextures[key], forceFrame*16, y*16, 16, 16, forceFrame*16, 0, 16, 16);
|
||||||
|
} else {
|
||||||
|
outCtx.drawImage(gTextures[key], 0, y*16, w, h, 0, 0, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GBS_recolor_fn()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
dark: parseColorStr("#071821"),
|
||||||
|
mid: parseColorStr("#86c06c"),
|
||||||
|
light: parseColorStr("#e0f8cf"),
|
||||||
|
bg: parseColorStr("#65ff00"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function GBS_recolor(ctx, w)
|
||||||
|
{
|
||||||
|
var imageData = ctx.getImageData(0, 0, w || 96, 16);
|
||||||
|
recolor(imageData.data, GBS_recolor_fn);
|
||||||
|
ctx.putImageData(imageData,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ff(ctx, src, f, sx, sy, dx)
|
||||||
|
{
|
||||||
|
f && ctx.save();
|
||||||
|
f && ctx.scale(-1, 1);
|
||||||
|
ctx.drawImage(src, 16*sx, sy*16, 16, 16, dx*16, 0, 16, 16);
|
||||||
|
f && ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
var FLIP = true;
|
||||||
|
|
||||||
|
function updateGBS()
|
||||||
|
{
|
||||||
|
ff(outCtx_gbs_s, outCanvas, null, 0, 0, 0);
|
||||||
|
ff(outCtx_gbs_s, outCanvas, null, 1, 0, 1);
|
||||||
|
ff(outCtx_gbs_s, outCanvas, FLIP, 2, 0, -3);
|
||||||
|
|
||||||
|
GBS_recolor(outCtx_gbs_s, 48);
|
||||||
|
|
||||||
|
updateExportLink("export_gbs_static", outCanvas_gbs_s, "_gbs");
|
||||||
|
|
||||||
|
ff(outCtx_gbs_a, outCanvas, null, 3, 0, 0)
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 3, 0, -2)
|
||||||
|
|
||||||
|
ff(outCtx_gbs_a, outCanvas, null, 4, 0, 3)
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 4, 0, -3)
|
||||||
|
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 2, 0, -5)
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 5, 0, -6)
|
||||||
|
|
||||||
|
GBS_recolor(outCtx_gbs_a, 96);
|
||||||
|
updateExportLink("export_gbs_animated", outCanvas_gbs_a, "_gbs_anim");
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseColorStr(str){
|
||||||
|
return [
|
||||||
|
parseInt(str.substr(1, 2), 16),
|
||||||
|
parseInt(str.substr(3, 2), 16),
|
||||||
|
parseInt(str.substr(5, 2), 16),
|
||||||
|
255
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColors()
|
||||||
|
{
|
||||||
|
function C(n){
|
||||||
|
return [
|
||||||
|
parseInt(COLORS[gColor][n].substr(1, 2), 16),
|
||||||
|
parseInt(COLORS[gColor][n].substr(3, 2), 16),
|
||||||
|
parseInt(COLORS[gColor][n].substr(5, 2), 16)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
var mode = gColorMode.split('').map(function(n){ return parseInt(n) });
|
||||||
|
var dark = C(mode[0]);
|
||||||
|
var mid = C(mode[1]);
|
||||||
|
var light = C(mode[2]);
|
||||||
|
|
||||||
|
var bg = C(3);
|
||||||
|
|
||||||
|
return { dark:dark, mid:mid, light:light, bg:bg };
|
||||||
|
}
|
||||||
|
|
||||||
|
function recolor(data, getColors)
|
||||||
|
{
|
||||||
|
var tmp = getColors();
|
||||||
|
var put1 = function(i, r, g, b, a) {
|
||||||
|
data[i+0] = r; data[i+1] = g; data[i+2] = b; data[i+3] = a;
|
||||||
|
}
|
||||||
|
for (var i=0; i<data.length; i+=4) {
|
||||||
|
var r = data[i];
|
||||||
|
if(r<50){
|
||||||
|
put1(i, tmp.dark[0], tmp.dark[1], tmp.dark[2], 255);
|
||||||
|
} else if(r<180){
|
||||||
|
put1(i, tmp.mid[0], tmp.mid[1], tmp.mid[2], 255);
|
||||||
|
} else if(r<245){
|
||||||
|
put1(i, tmp.light[0], tmp.light[1], tmp.light[2], 255);
|
||||||
|
} else {
|
||||||
|
put1(i, tmp.bg[0], tmp.bg[1], tmp.bg[2], tmp.bg[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateExportLink(id, canvas, suffix)
|
||||||
|
{
|
||||||
|
// it's always a small file so this should be good enough:
|
||||||
|
var str = Object.keys(gParts).sort().map(function(k){
|
||||||
|
return ("00"+gParts[k]).slice(-2);
|
||||||
|
}).join('')
|
||||||
|
var exportlink = document.getElementById(id)
|
||||||
|
exportlink.href = canvas.toDataURL("image/png");
|
||||||
|
exportlink.download = str + suffix + '.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOutCanvas() {
|
||||||
|
outCtx.clearRect(0, 0, outCanvas.width, outCanvas.height);
|
||||||
|
|
||||||
|
outCtx.drawImage(gTextures['base'], 0, 0); // base
|
||||||
|
|
||||||
|
drawPart("hair");
|
||||||
|
drawPart("torso");
|
||||||
|
drawPart("ears");
|
||||||
|
drawPart("mouth");
|
||||||
|
drawPart("eyes");
|
||||||
|
drawPart("hands", 0);
|
||||||
|
|
||||||
|
// back of the hair
|
||||||
|
drawPart("hair", null, 4);
|
||||||
|
drawPart("hair", null, 1);
|
||||||
|
|
||||||
|
updateGBS()
|
||||||
|
|
||||||
|
|
||||||
|
var imageData = outCtx.getImageData(0, 0, outCanvas.width, outCanvas.height);
|
||||||
|
var data = imageData.data
|
||||||
|
|
||||||
|
recolor(data, getColors);
|
||||||
|
|
||||||
|
outCtx.putImageData(imageData,0,0);
|
||||||
|
|
||||||
|
updateExportLink("exportlink", outCanvas, "_" + gColor + gColorMode)
|
||||||
|
// // it's always a small file so this should be good enough:
|
||||||
|
// var str = Object.keys(gParts).sort().map(function(k){
|
||||||
|
// return ("00"+gParts[k]).slice(-2);
|
||||||
|
// }).join('') + "_" + gColor + gColorMode;
|
||||||
|
// var exportlink = document.getElementById("exportlink")
|
||||||
|
// exportlink.href = outCanvas.toDataURL("image/png");
|
||||||
|
// exportlink.download = str + '.png';
|
||||||
|
// document.getElementById('serialized_input').value = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prefixInputWithASpan(input, text){
|
||||||
|
var span = document.createElement("span");
|
||||||
|
span.innerText = text;
|
||||||
|
input.parentElement.prepend(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupInput(key){
|
||||||
|
var input = document.getElementById(key + "Input");
|
||||||
|
prefixInputWithASpan(input, key)
|
||||||
|
input.setAttribute('min', 0);
|
||||||
|
input.setAttribute('max', PARTS_MAX[key]);
|
||||||
|
input.value = parseInt(Math.random() * (PARTS_MAX[key] + 1));
|
||||||
|
var inputUpdate = function(e){
|
||||||
|
gParts[key] = parseInt(e.target.value);
|
||||||
|
console.log("INPUT UPDATE", e.target.value, gParts);
|
||||||
|
updateOutCanvas();
|
||||||
|
}
|
||||||
|
inputUpdate({ target: input });
|
||||||
|
input.onchange = inputUpdate;
|
||||||
|
input.oninput = inputUpdate;
|
||||||
|
};
|
||||||
|
|
||||||
|
function setupColorInput() {
|
||||||
|
var key = 'color';
|
||||||
|
var input = document.getElementById(key + "Input");
|
||||||
|
prefixInputWithASpan(input, 'colors')
|
||||||
|
|
||||||
|
input.setAttribute('min', 0);
|
||||||
|
input.setAttribute('max', COLORS.length - 1);
|
||||||
|
PARTS_MAX['color'] = COLORS.length;
|
||||||
|
input.value = 0;
|
||||||
|
var inputUpdate = function(e){
|
||||||
|
gColor = parseInt(e.target.value);
|
||||||
|
console.log("COLOR UPDATE", e.target.value, gColor);
|
||||||
|
document.getElementById('colorinfo').innerText = COLORS[gColor][4];
|
||||||
|
updateOutCanvas();
|
||||||
|
}
|
||||||
|
inputUpdate({ target: input });
|
||||||
|
input.onchange = inputUpdate;
|
||||||
|
input.oninput = inputUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupColorMode() {
|
||||||
|
var btn = document.getElementById("colormode");
|
||||||
|
|
||||||
|
btn.onclick = function() {
|
||||||
|
if(gColorMode == '012'){ gColorMode = '023' }
|
||||||
|
else if(gColorMode == '023'){ gColorMode = '013' }
|
||||||
|
else if(gColorMode == '013'){ gColorMode = '123' }
|
||||||
|
else { gColorMode = '012' }
|
||||||
|
|
||||||
|
btn.innerText = gColorMode;
|
||||||
|
|
||||||
|
updateOutCanvas();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
terms.json: terms.yaml
|
||||||
|
python3 update_terms_yaml_to_json.py $< $@
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 308 B |
@ -0,0 +1,46 @@
|
|||||||
|
.creature canvas {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
image-rendering: optimizeSpeed;
|
||||||
|
image-rendering: -moz-crisp-edges;
|
||||||
|
image-rendering: -webkit-optimize-contrast;
|
||||||
|
image-rendering: -o-crisp-edges;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
-ms-interpolation-mode: nearest-neighbor;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.creature {
|
||||||
|
display: inline-block;
|
||||||
|
width: fit-content;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin: 10em;
|
||||||
|
}
|
||||||
|
div.centerbottom {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
div.caption {
|
||||||
|
/* border: 1px solid black; */
|
||||||
|
position: absolute;
|
||||||
|
left: -120px;
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
div.caption .corner {
|
||||||
|
width: 11px;
|
||||||
|
height: 11px;
|
||||||
|
position: absolute;
|
||||||
|
top: -9px;
|
||||||
|
left: 49%;
|
||||||
|
background-image: url("corner.png");
|
||||||
|
}
|
||||||
|
div.caption div.captiontext {
|
||||||
|
/* height: 4em; */
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid black;
|
||||||
|
/* top | right | bottom | left */
|
||||||
|
padding: 0 0.3em 0.3em 0.3em;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
|||||||
|
var a = function(n) {
|
||||||
|
return n
|
||||||
|
.split(',')
|
||||||
|
.map(function(k){ return { x: parseInt(k), f: !!k.match('f')} });
|
||||||
|
}
|
||||||
|
var ANIMS = {
|
||||||
|
stand: a("0"),
|
||||||
|
rotate: a("0,2f,1,2"),
|
||||||
|
run_front: a("0,3,0f,3f"),
|
||||||
|
run_back: a("1,4,1f,4f"),
|
||||||
|
run_left: a("2,5"),
|
||||||
|
run_right: a("2f,5f"),
|
||||||
|
}
|
||||||
|
|
||||||
|
class Creature {
|
||||||
|
constructor(img) {
|
||||||
|
this.img = img;
|
||||||
|
if (img.complete) {
|
||||||
|
this.init();
|
||||||
|
} else {
|
||||||
|
img.addEventListener("load", this.init.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
init () {
|
||||||
|
this.div = document.createElement("div");
|
||||||
|
this.div.classList.add("creature");
|
||||||
|
this.canvas = document.createElement("canvas");
|
||||||
|
this.img.parentNode.replaceChild(this.div, this.img);
|
||||||
|
this.div.appendChild(this.canvas);
|
||||||
|
this.ctx = this.canvas.getContext("2d");
|
||||||
|
this.canvas.width = 16;
|
||||||
|
this.canvas.height = 16;
|
||||||
|
this.ctx.drawImage(this.img, 0, 0);
|
||||||
|
// this.canvas.title = this.img.title;
|
||||||
|
this.centerbottom = document.createElement("div");
|
||||||
|
this.centerbottom.classList.add("centerbottom");
|
||||||
|
this.caption_div = document.createElement("div");
|
||||||
|
this.caption_corner = document.createElement("div");
|
||||||
|
this.caption = document.createElement("div");
|
||||||
|
this.caption_div.classList.add("caption");
|
||||||
|
this.caption_corner.classList.add("corner");
|
||||||
|
this.caption.classList.add("captiontext");
|
||||||
|
this.caption_div.appendChild(this.caption_corner);
|
||||||
|
this.caption_div.appendChild(this.caption);
|
||||||
|
this.div.appendChild(this.centerbottom);
|
||||||
|
this.centerbottom.appendChild(this.caption_div);
|
||||||
|
this.caption.textContent = this.img.title;
|
||||||
|
this.currentAnimName = "stand";
|
||||||
|
this.canvas.addEventListener("click", this.click.bind(this));
|
||||||
|
}
|
||||||
|
animate(){
|
||||||
|
this.ctx.clearRect(0, 0, 16, 16);
|
||||||
|
var t = Date.now ? Date.now() : +(new Date());
|
||||||
|
|
||||||
|
var nt = parseInt(t / 200)
|
||||||
|
var anim = ANIMS[this.currentAnimName];
|
||||||
|
var len = anim.length;
|
||||||
|
|
||||||
|
var findex = nt % len;
|
||||||
|
var frame = anim[findex];
|
||||||
|
const ctx = this.ctx;
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
if(frame.f){
|
||||||
|
this.ctx.translate(16, 0);
|
||||||
|
this.ctx.scale(-1, 1);
|
||||||
|
}
|
||||||
|
ctx.drawImage(this.img, frame.x * 16, 0, 16, 16, 0, 0, 16, 16);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
click () {
|
||||||
|
console.log("click", this);
|
||||||
|
this.currentAnimName = "run_front";
|
||||||
|
window.setInterval(this.animate.bind(this), 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document.querySelectorAll("img.creature").forEach ( img => {
|
||||||
|
new Creature(img);
|
||||||
|
})
|
@ -0,0 +1,83 @@
|
|||||||
|
body, html { background: #fff; text-align: center; }
|
||||||
|
* { box-sizing: border-box; font-family: monospace; font-size: 14px; }
|
||||||
|
h1 { font-size: 28px; margin: 0 0 10px 0; padding: 0; }
|
||||||
|
#root {
|
||||||
|
width: 460px;
|
||||||
|
/* white-space: nowrap; */
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
image-rendering: optimizeSpeed;
|
||||||
|
image-rendering: -moz-crisp-edges;
|
||||||
|
image-rendering: -webkit-optimize-contrast;
|
||||||
|
image-rendering: -o-crisp-edges;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
-ms-interpolation-mode: nearest-neighbor;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
#c { width: 144px; height: 144px; padding: 8px; border: none; }
|
||||||
|
|
||||||
|
#outc,
|
||||||
|
#outc_gbs_s,
|
||||||
|
#outc_gbs_a {
|
||||||
|
height: 64px;
|
||||||
|
padding: 8px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
label { display: block; }
|
||||||
|
label > input { width: 240px; }
|
||||||
|
label > span { display: inline-block; vertical-align: middle; width: 55px; }
|
||||||
|
input[type=range]{ vertical-align: middle; }
|
||||||
|
|
||||||
|
#inputs { display: inline-block; vertical-align: top; text-align: left; margin-top: 1em;}
|
||||||
|
|
||||||
|
.btn, button { background: #fff; text-align: center; min-width: 144px; display: inline-block; padding: 16px 32px; border: 1px solid black; color: black; text-decoration: none; font-size: 1em; margin: 0 0 10px 0; }
|
||||||
|
.btn:hover, button:hover { background: #eee }
|
||||||
|
.btn:active, button:active{ background: #ccc }
|
||||||
|
|
||||||
|
.sm {
|
||||||
|
min-width: 40px;
|
||||||
|
padding: 10px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rootloading { display: none }
|
||||||
|
|
||||||
|
div.colormode { max-width: 240px; white-space: nowrap }
|
||||||
|
|
||||||
|
#caption {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.caption {
|
||||||
|
/* border: 3px solid black; */
|
||||||
|
position: relative;
|
||||||
|
width: fit-content;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
div.caption .corner {
|
||||||
|
width: 11px;
|
||||||
|
height: 11px;
|
||||||
|
position: absolute;
|
||||||
|
top: -9px;
|
||||||
|
left: 49%;
|
||||||
|
background-image: url("corner.png");
|
||||||
|
}
|
||||||
|
div.caption textarea {
|
||||||
|
width: 320px;
|
||||||
|
height: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#colofon {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
#info, #info p {
|
||||||
|
font-family: serif;
|
||||||
|
}
|
||||||
|
#info {
|
||||||
|
padding: 0 1em 0 1em;
|
||||||
|
border: 1px solid black;
|
||||||
|
text-align: left;
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
/* https://codepen.io/josfabre/pen/EBMWwW */
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #CCC;
|
||||||
|
padding: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Press Start 2P", cursive;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.3em;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
padding: 4px;
|
||||||
|
box-shadow: 0 -4px #fff, 0 -8px #000, 4px 0 #fff, 4px -4px #000, 8px 0 #000, 0 4px #fff, 0 8px #000, -4px 0 #fff, -4px 4px #000, -8px 0 #000, -4px -4px #000, 4px 4px #000;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
.bubble::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.bubble.shadow {
|
||||||
|
box-shadow: 0 -4px #fff, 0 -8px #000, 4px 0 #fff, 4px -4px #000, 8px 0 #000, 0 4px #fff, 0 8px #000, -4px 0 #fff, -4px 4px #000, -8px 0 #000, -4px -4px #000, 4px 4px #000, 4px 12px rgba(0, 0, 0, 0.1), 12px 4px rgba(0, 0, 0, 0.1), 8px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
.bubble.mini {
|
||||||
|
width: 110px;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 4px;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
.bubble.medium {
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
.bubble.large {
|
||||||
|
width: 560px;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: left;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.bubble.grow {
|
||||||
|
width: initial;
|
||||||
|
}
|
||||||
|
.bubble.top::after {
|
||||||
|
height: 4px;
|
||||||
|
width: 4px;
|
||||||
|
top: -8px;
|
||||||
|
left: 32px;
|
||||||
|
box-shadow: 0 -4px #000, 0 -8px #000, 0 -12px #000, 0 -16px #000, -4px -12px #000, -8px -8px #000, -12px -4px #000, -4px -4px #fff, -8px -4px #fff, -4px -8px #fff, -4px 0 #fff, -8px 0 #fff, -12px 0 #fff;
|
||||||
|
}
|
||||||
|
.bubble.right::after {
|
||||||
|
height: 4px;
|
||||||
|
width: 4px;
|
||||||
|
top: 84px;
|
||||||
|
right: -8px;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 4px -4px #fff, 4px 0 #fff, 8px 0 #fff, 0 -8px #fff, 4px 4px #000, 8px 4px #000, 12px 4px #000, 16px 4px #000, 12px 0 #000, 8px -4px #000, 4px -8px #000, 0 -4px #fff;
|
||||||
|
}
|
||||||
|
.bubble.bottom::after {
|
||||||
|
height: 4px;
|
||||||
|
width: 4px;
|
||||||
|
bottom: -8px;
|
||||||
|
left: 32px;
|
||||||
|
box-shadow: 0 4px #000, 0 8px #000, 0 12px #000, 0 16px #000, -4px 12px #000, -8px 8px #000, -12px 4px #000, -4px 4px #fff, -8px 4px #fff, -4px 8px #fff, -4px 0 #fff, -8px 0 #fff, -12px 0 #fff;
|
||||||
|
}
|
||||||
|
.bubble.left::after {
|
||||||
|
height: 4px;
|
||||||
|
width: 4px;
|
||||||
|
top: 20px;
|
||||||
|
left: -8px;
|
||||||
|
background: white;
|
||||||
|
box-shadow: -4px -4px #fff, -4px 0 #fff, -8px 0 #fff, 0 -8px #fff, -4px 4px #000, -8px 4px #000, -12px 4px #000, -16px 4px #000, -12px 0 #000, -8px -4px #000, -4px -8px #000, 0 -4px #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 6em;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble textarea:focus {
|
||||||
|
outline: none !important;
|
||||||
|
border: none;
|
||||||
|
/* box-shadow: 0 0 10px #719ECE; */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
canvas.creature {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
image-rendering: optimizeSpeed;
|
||||||
|
image-rendering: -moz-crisp-edges;
|
||||||
|
image-rendering: -webkit-optimize-contrast;
|
||||||
|
image-rendering: -o-crisp-edges;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
-ms-interpolation-mode: nearest-neighbor;
|
||||||
|
border: none;
|
||||||
|
}
|
@ -0,0 +1,332 @@
|
|||||||
|
{
|
||||||
|
"intro": [
|
||||||
|
"I'm a(n)",
|
||||||
|
"I am a(n)",
|
||||||
|
"I aim to be a(n)",
|
||||||
|
"Some call me a(n)",
|
||||||
|
"I'm known to be a(n)",
|
||||||
|
"Someday I will be a(n)"
|
||||||
|
],
|
||||||
|
"action": [
|
||||||
|
"researching",
|
||||||
|
"studying",
|
||||||
|
"scanning",
|
||||||
|
"inflitrating",
|
||||||
|
"uploading",
|
||||||
|
"seeding",
|
||||||
|
"screening",
|
||||||
|
"spamming",
|
||||||
|
"tweeting",
|
||||||
|
"tooting",
|
||||||
|
"singing",
|
||||||
|
"feeling",
|
||||||
|
"listening to",
|
||||||
|
"playing",
|
||||||
|
"reading",
|
||||||
|
"disrupting",
|
||||||
|
"acting as",
|
||||||
|
"dancing",
|
||||||
|
"seeing",
|
||||||
|
"cooking",
|
||||||
|
"preaching",
|
||||||
|
"translating",
|
||||||
|
"yelling",
|
||||||
|
"screaming",
|
||||||
|
"running",
|
||||||
|
"whistleblowing",
|
||||||
|
"leaking",
|
||||||
|
"painting",
|
||||||
|
"writing",
|
||||||
|
"laughing at",
|
||||||
|
"dictating",
|
||||||
|
"designing",
|
||||||
|
"destroying",
|
||||||
|
"showing",
|
||||||
|
"debating",
|
||||||
|
"creating",
|
||||||
|
"performing",
|
||||||
|
"building",
|
||||||
|
"hiding",
|
||||||
|
"surveilling",
|
||||||
|
"faking",
|
||||||
|
"banning",
|
||||||
|
"watching",
|
||||||
|
"deciding",
|
||||||
|
"dealing",
|
||||||
|
"exchanging",
|
||||||
|
"mediating",
|
||||||
|
"fighting",
|
||||||
|
"vandalizing",
|
||||||
|
"parodying",
|
||||||
|
"questioning",
|
||||||
|
"criticizing",
|
||||||
|
"provoking",
|
||||||
|
"obscuring",
|
||||||
|
"shouting on",
|
||||||
|
"controlling",
|
||||||
|
"demanding",
|
||||||
|
"delivering",
|
||||||
|
"disclosing",
|
||||||
|
"developing",
|
||||||
|
"divulging",
|
||||||
|
"lying about",
|
||||||
|
"bragging about",
|
||||||
|
"echoing",
|
||||||
|
"portraying",
|
||||||
|
"helping",
|
||||||
|
"hiding",
|
||||||
|
"interrupting",
|
||||||
|
"conspiring",
|
||||||
|
"sending",
|
||||||
|
"repairing",
|
||||||
|
"disagreeing"
|
||||||
|
],
|
||||||
|
"actor": [
|
||||||
|
"hipster",
|
||||||
|
"scener",
|
||||||
|
"seeder",
|
||||||
|
"leecher",
|
||||||
|
"pirate",
|
||||||
|
"librarian",
|
||||||
|
"virus",
|
||||||
|
"AI",
|
||||||
|
"wizard",
|
||||||
|
"quant",
|
||||||
|
"CEO",
|
||||||
|
"shareholder",
|
||||||
|
"user",
|
||||||
|
"stenographer",
|
||||||
|
"maker",
|
||||||
|
"artist",
|
||||||
|
"professional",
|
||||||
|
"hobbyist",
|
||||||
|
"amateur",
|
||||||
|
"teacher",
|
||||||
|
"student",
|
||||||
|
"doctor",
|
||||||
|
"patient",
|
||||||
|
"public",
|
||||||
|
"criminal",
|
||||||
|
"cook",
|
||||||
|
"editor",
|
||||||
|
"programmer",
|
||||||
|
"preacher",
|
||||||
|
"livecoder",
|
||||||
|
"individual",
|
||||||
|
"visitor",
|
||||||
|
"hacker",
|
||||||
|
"reader",
|
||||||
|
"consumer",
|
||||||
|
"mediator",
|
||||||
|
"actor",
|
||||||
|
"builder",
|
||||||
|
"child",
|
||||||
|
"adult",
|
||||||
|
"architect",
|
||||||
|
"tourist",
|
||||||
|
"person",
|
||||||
|
"parent",
|
||||||
|
"photographer",
|
||||||
|
"musician",
|
||||||
|
"designer",
|
||||||
|
"chatbot",
|
||||||
|
"regulator",
|
||||||
|
"dancer",
|
||||||
|
"developer",
|
||||||
|
"author",
|
||||||
|
"robot",
|
||||||
|
"dog",
|
||||||
|
"cat",
|
||||||
|
"judge",
|
||||||
|
"celebrity",
|
||||||
|
"computer",
|
||||||
|
"politician",
|
||||||
|
"president",
|
||||||
|
"manager",
|
||||||
|
"entrepreneur",
|
||||||
|
"whistleblower",
|
||||||
|
"infiltrator",
|
||||||
|
"book binder",
|
||||||
|
"collective"
|
||||||
|
],
|
||||||
|
"media": [
|
||||||
|
"image boards",
|
||||||
|
"forums",
|
||||||
|
"warez",
|
||||||
|
"screens",
|
||||||
|
"galleries",
|
||||||
|
"screensavers",
|
||||||
|
"viruses",
|
||||||
|
"frequencies",
|
||||||
|
"files",
|
||||||
|
"operating systems",
|
||||||
|
"databases",
|
||||||
|
"privacy",
|
||||||
|
"posters",
|
||||||
|
"cybernetics",
|
||||||
|
"floppy disks",
|
||||||
|
"CD-ROMs",
|
||||||
|
"LaserDiscs",
|
||||||
|
"apps",
|
||||||
|
"spam",
|
||||||
|
"startups",
|
||||||
|
"manuscripts",
|
||||||
|
"carpets",
|
||||||
|
"markets",
|
||||||
|
"architectures",
|
||||||
|
"feels",
|
||||||
|
"books",
|
||||||
|
"games",
|
||||||
|
"radio",
|
||||||
|
"music",
|
||||||
|
"graffitis",
|
||||||
|
"blogs",
|
||||||
|
"theatre",
|
||||||
|
"woodblocks",
|
||||||
|
"dances",
|
||||||
|
"recycling",
|
||||||
|
"emails",
|
||||||
|
"food",
|
||||||
|
"migration",
|
||||||
|
"magazines",
|
||||||
|
"maps",
|
||||||
|
"comics",
|
||||||
|
"finance",
|
||||||
|
"teaching",
|
||||||
|
"memes",
|
||||||
|
"futures",
|
||||||
|
"traditions",
|
||||||
|
"corruption",
|
||||||
|
"regulation",
|
||||||
|
"porn",
|
||||||
|
"webpages",
|
||||||
|
"vandalism",
|
||||||
|
"samizdat",
|
||||||
|
"ethics",
|
||||||
|
"billboards",
|
||||||
|
"advertising",
|
||||||
|
"manifestos",
|
||||||
|
"leaflets",
|
||||||
|
"browsers",
|
||||||
|
"wikis",
|
||||||
|
"canvases",
|
||||||
|
"tapes",
|
||||||
|
"vinyls",
|
||||||
|
"records",
|
||||||
|
"synthesizers",
|
||||||
|
"feeds",
|
||||||
|
"newspapers",
|
||||||
|
"HTML pages",
|
||||||
|
"codex",
|
||||||
|
"software",
|
||||||
|
"codes of conduct",
|
||||||
|
"epubs",
|
||||||
|
"PDFs",
|
||||||
|
"NFTs",
|
||||||
|
"stories",
|
||||||
|
"dictionaries",
|
||||||
|
"libraries",
|
||||||
|
"bugs",
|
||||||
|
"disagreements"
|
||||||
|
],
|
||||||
|
"prefix": [
|
||||||
|
"proto",
|
||||||
|
"xeno",
|
||||||
|
"cyber",
|
||||||
|
"retro",
|
||||||
|
"pre",
|
||||||
|
"ante",
|
||||||
|
"proto",
|
||||||
|
"post",
|
||||||
|
"avant",
|
||||||
|
"neo",
|
||||||
|
"anti",
|
||||||
|
"co",
|
||||||
|
"epi",
|
||||||
|
"ex",
|
||||||
|
"extra",
|
||||||
|
"hyper",
|
||||||
|
"infra",
|
||||||
|
"inter",
|
||||||
|
"macro",
|
||||||
|
"micro",
|
||||||
|
"mid",
|
||||||
|
"mono",
|
||||||
|
"non",
|
||||||
|
"multi",
|
||||||
|
"omni",
|
||||||
|
"semi",
|
||||||
|
"sub",
|
||||||
|
"super",
|
||||||
|
"trans",
|
||||||
|
"cross",
|
||||||
|
"uni",
|
||||||
|
"minor"
|
||||||
|
],
|
||||||
|
"sort": [
|
||||||
|
"bootleg",
|
||||||
|
"capitalist",
|
||||||
|
"progressive",
|
||||||
|
"organic",
|
||||||
|
"industrial",
|
||||||
|
"homemade",
|
||||||
|
"craft",
|
||||||
|
"AI",
|
||||||
|
"encrypted",
|
||||||
|
"inclusive",
|
||||||
|
"fair",
|
||||||
|
"transparent",
|
||||||
|
"command line",
|
||||||
|
"granular",
|
||||||
|
"crypto",
|
||||||
|
"centralised",
|
||||||
|
"free",
|
||||||
|
"libre",
|
||||||
|
"open",
|
||||||
|
"proprietary",
|
||||||
|
"DIY",
|
||||||
|
"DIWO",
|
||||||
|
"homebrew",
|
||||||
|
"decentralised",
|
||||||
|
"closed source",
|
||||||
|
"binary",
|
||||||
|
"plaintext",
|
||||||
|
"federated",
|
||||||
|
"distributed",
|
||||||
|
"online",
|
||||||
|
"offline",
|
||||||
|
"raw",
|
||||||
|
"compressed",
|
||||||
|
"deep",
|
||||||
|
"dark",
|
||||||
|
"common",
|
||||||
|
"shared",
|
||||||
|
"liberal",
|
||||||
|
"anarcho-capitalist",
|
||||||
|
"anarcho-communist",
|
||||||
|
"anarcho-syndicalist",
|
||||||
|
"authoritarian",
|
||||||
|
"capitalist",
|
||||||
|
"communist",
|
||||||
|
"marxist",
|
||||||
|
"apolitical",
|
||||||
|
"syndicated",
|
||||||
|
"digital",
|
||||||
|
"analog",
|
||||||
|
"bottom-up",
|
||||||
|
"top-down",
|
||||||
|
"horizontal",
|
||||||
|
"vertical",
|
||||||
|
"agonistic",
|
||||||
|
"version-controlled",
|
||||||
|
"feminist",
|
||||||
|
"decolonial",
|
||||||
|
"contradictory",
|
||||||
|
"occasional",
|
||||||
|
"layered",
|
||||||
|
"entangled",
|
||||||
|
"collective",
|
||||||
|
"complex",
|
||||||
|
"artificial"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,324 @@
|
|||||||
|
intro:
|
||||||
|
- I'm a(n)
|
||||||
|
- I am a(n)
|
||||||
|
- I aim to be a(n)
|
||||||
|
- Some call me a(n)
|
||||||
|
- I'm known to be a(n)
|
||||||
|
- Someday I will be a(n)
|
||||||
|
action:
|
||||||
|
- researching
|
||||||
|
- studying
|
||||||
|
- scanning
|
||||||
|
- inflitrating
|
||||||
|
- uploading
|
||||||
|
- seeding
|
||||||
|
- screening
|
||||||
|
- spamming
|
||||||
|
- tweeting
|
||||||
|
- tooting
|
||||||
|
- singing
|
||||||
|
- feeling
|
||||||
|
- listening to
|
||||||
|
- playing
|
||||||
|
- reading
|
||||||
|
- disrupting
|
||||||
|
- acting as
|
||||||
|
- dancing
|
||||||
|
- seeing
|
||||||
|
- cooking
|
||||||
|
- preaching
|
||||||
|
- translating
|
||||||
|
- yelling
|
||||||
|
- screaming
|
||||||
|
- running
|
||||||
|
- whistleblowing
|
||||||
|
- leaking
|
||||||
|
- painting
|
||||||
|
- writing
|
||||||
|
- laughing at
|
||||||
|
- dictating
|
||||||
|
- designing
|
||||||
|
- destroying
|
||||||
|
- showing
|
||||||
|
- debating
|
||||||
|
- creating
|
||||||
|
- performing
|
||||||
|
- building
|
||||||
|
- hiding
|
||||||
|
- surveilling
|
||||||
|
- faking
|
||||||
|
- banning
|
||||||
|
- watching
|
||||||
|
- deciding
|
||||||
|
- dealing
|
||||||
|
- exchanging
|
||||||
|
- mediating
|
||||||
|
- fighting
|
||||||
|
- vandalizing
|
||||||
|
- parodying
|
||||||
|
- questioning
|
||||||
|
- criticizing
|
||||||
|
- provoking
|
||||||
|
- obscuring
|
||||||
|
- shouting on
|
||||||
|
- controlling
|
||||||
|
- demanding
|
||||||
|
- delivering
|
||||||
|
- disclosing
|
||||||
|
- developing
|
||||||
|
- divulging
|
||||||
|
- lying about
|
||||||
|
- bragging about
|
||||||
|
- echoing
|
||||||
|
- portraying
|
||||||
|
- helping
|
||||||
|
- hiding
|
||||||
|
- interrupting
|
||||||
|
- conspiring
|
||||||
|
- sending
|
||||||
|
- repairing
|
||||||
|
- disagreeing
|
||||||
|
actor:
|
||||||
|
- hipster
|
||||||
|
- scener
|
||||||
|
- seeder
|
||||||
|
- leecher
|
||||||
|
- pirate
|
||||||
|
- librarian
|
||||||
|
- virus
|
||||||
|
- AI
|
||||||
|
- wizard
|
||||||
|
- quant
|
||||||
|
- CEO
|
||||||
|
- shareholder
|
||||||
|
- user
|
||||||
|
- stenographer
|
||||||
|
- maker
|
||||||
|
- artist
|
||||||
|
- professional
|
||||||
|
- hobbyist
|
||||||
|
- amateur
|
||||||
|
- teacher
|
||||||
|
- student
|
||||||
|
- doctor
|
||||||
|
- patient
|
||||||
|
- public
|
||||||
|
- criminal
|
||||||
|
- cook
|
||||||
|
- editor
|
||||||
|
- programmer
|
||||||
|
- preacher
|
||||||
|
- livecoder
|
||||||
|
- individual
|
||||||
|
- visitor
|
||||||
|
- hacker
|
||||||
|
- reader
|
||||||
|
- consumer
|
||||||
|
- mediator
|
||||||
|
- actor
|
||||||
|
- builder
|
||||||
|
- child
|
||||||
|
- adult
|
||||||
|
- architect
|
||||||
|
- tourist
|
||||||
|
- person
|
||||||
|
- parent
|
||||||
|
- photographer
|
||||||
|
- musician
|
||||||
|
- designer
|
||||||
|
- chatbot
|
||||||
|
- regulator
|
||||||
|
- dancer
|
||||||
|
- developer
|
||||||
|
- author
|
||||||
|
- robot
|
||||||
|
- dog
|
||||||
|
- cat
|
||||||
|
- judge
|
||||||
|
- celebrity
|
||||||
|
- computer
|
||||||
|
- politician
|
||||||
|
- president
|
||||||
|
- manager
|
||||||
|
- entrepreneur
|
||||||
|
- whistleblower
|
||||||
|
- infiltrator
|
||||||
|
- book binder
|
||||||
|
- collective
|
||||||
|
media:
|
||||||
|
- image boards
|
||||||
|
- forums
|
||||||
|
- warez
|
||||||
|
- screens
|
||||||
|
- galleries
|
||||||
|
- screensavers
|
||||||
|
- viruses
|
||||||
|
- frequencies
|
||||||
|
- files
|
||||||
|
- operating systems
|
||||||
|
- databases
|
||||||
|
- privacy
|
||||||
|
- posters
|
||||||
|
- cybernetics
|
||||||
|
- floppy disks
|
||||||
|
- CD-ROMs
|
||||||
|
- LaserDiscs
|
||||||
|
- apps
|
||||||
|
- spam
|
||||||
|
- startups
|
||||||
|
- manuscripts
|
||||||
|
- carpets
|
||||||
|
- markets
|
||||||
|
- architectures
|
||||||
|
- feels
|
||||||
|
- books
|
||||||
|
- games
|
||||||
|
- radio
|
||||||
|
- music
|
||||||
|
- graffitis
|
||||||
|
- blogs
|
||||||
|
- theatre
|
||||||
|
- woodblocks
|
||||||
|
- dances
|
||||||
|
- recycling
|
||||||
|
- emails
|
||||||
|
- food
|
||||||
|
- migration
|
||||||
|
- magazines
|
||||||
|
- maps
|
||||||
|
- comics
|
||||||
|
- finance
|
||||||
|
- teaching
|
||||||
|
- memes
|
||||||
|
- futures
|
||||||
|
- traditions
|
||||||
|
- corruption
|
||||||
|
- regulation
|
||||||
|
- porn
|
||||||
|
- webpages
|
||||||
|
- vandalism
|
||||||
|
- samizdat
|
||||||
|
- ethics
|
||||||
|
- billboards
|
||||||
|
- advertising
|
||||||
|
- manifestos
|
||||||
|
- leaflets
|
||||||
|
- browsers
|
||||||
|
- wikis
|
||||||
|
- canvases
|
||||||
|
- tapes
|
||||||
|
- vinyls
|
||||||
|
- records
|
||||||
|
- synthesizers
|
||||||
|
- feeds
|
||||||
|
- newspapers
|
||||||
|
- HTML pages
|
||||||
|
- codex
|
||||||
|
- software
|
||||||
|
- codes of conduct
|
||||||
|
- epubs
|
||||||
|
- PDFs
|
||||||
|
- NFTs
|
||||||
|
- stories
|
||||||
|
- dictionaries
|
||||||
|
- libraries
|
||||||
|
- bugs
|
||||||
|
- disagreements
|
||||||
|
prefix:
|
||||||
|
- proto
|
||||||
|
- xeno
|
||||||
|
- cyber
|
||||||
|
- retro
|
||||||
|
- pre
|
||||||
|
- ante
|
||||||
|
- proto
|
||||||
|
- post
|
||||||
|
- avant
|
||||||
|
- neo
|
||||||
|
- anti
|
||||||
|
- co
|
||||||
|
- epi
|
||||||
|
- ex
|
||||||
|
- extra
|
||||||
|
- hyper
|
||||||
|
- infra
|
||||||
|
- inter
|
||||||
|
- macro
|
||||||
|
- micro
|
||||||
|
- mid
|
||||||
|
- mono
|
||||||
|
- non
|
||||||
|
- multi
|
||||||
|
- omni
|
||||||
|
- semi
|
||||||
|
- sub
|
||||||
|
- super
|
||||||
|
- trans
|
||||||
|
- cross
|
||||||
|
- uni
|
||||||
|
- minor
|
||||||
|
sort:
|
||||||
|
- bootleg
|
||||||
|
- capitalist
|
||||||
|
- progressive
|
||||||
|
- organic
|
||||||
|
- industrial
|
||||||
|
- homemade
|
||||||
|
- craft
|
||||||
|
- AI
|
||||||
|
- encrypted
|
||||||
|
- inclusive
|
||||||
|
- fair
|
||||||
|
- transparent
|
||||||
|
- command line
|
||||||
|
- granular
|
||||||
|
- crypto
|
||||||
|
- centralised
|
||||||
|
- free
|
||||||
|
- libre
|
||||||
|
- open
|
||||||
|
- proprietary
|
||||||
|
- DIY
|
||||||
|
- DIWO
|
||||||
|
- homebrew
|
||||||
|
- decentralised
|
||||||
|
- closed source
|
||||||
|
- binary
|
||||||
|
- plaintext
|
||||||
|
- federated
|
||||||
|
- distributed
|
||||||
|
- online
|
||||||
|
- offline
|
||||||
|
- raw
|
||||||
|
- compressed
|
||||||
|
- deep
|
||||||
|
- dark
|
||||||
|
- common
|
||||||
|
- shared
|
||||||
|
- liberal
|
||||||
|
- anarcho-capitalist
|
||||||
|
- anarcho-communist
|
||||||
|
- anarcho-syndicalist
|
||||||
|
- authoritarian
|
||||||
|
- capitalist
|
||||||
|
- communist
|
||||||
|
- marxist
|
||||||
|
- apolitical
|
||||||
|
- syndicated
|
||||||
|
- digital
|
||||||
|
- analog
|
||||||
|
- bottom-up
|
||||||
|
- top-down
|
||||||
|
- horizontal
|
||||||
|
- vertical
|
||||||
|
- agonistic
|
||||||
|
- version-controlled
|
||||||
|
- feminist
|
||||||
|
- decolonial
|
||||||
|
- contradictory
|
||||||
|
- occasional
|
||||||
|
- layered
|
||||||
|
- entangled
|
||||||
|
- collective
|
||||||
|
- complex
|
||||||
|
- artificial
|
@ -0,0 +1,16 @@
|
|||||||
|
import click
|
||||||
|
import yaml
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.argument('input', type=click.File('r'))
|
||||||
|
@click.argument('output', type=click.File('w'))
|
||||||
|
@click.argument('indent', type=int, default=2)
|
||||||
|
def yaml_to_json(input, output, indent):
|
||||||
|
"""Convert a YAML input to JSON output"""
|
||||||
|
d = yaml.safe_load(input)
|
||||||
|
json.dump(d, output, indent=indent)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
yaml_to_json()
|
@ -0,0 +1,9 @@
|
|||||||
|
canvas {
|
||||||
|
image-rendering: optimizeSpeed;
|
||||||
|
image-rendering: -moz-crisp-edges;
|
||||||
|
image-rendering: -webkit-optimize-contrast;
|
||||||
|
image-rendering: -o-crisp-edges;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
-ms-interpolation-mode: nearest-neighbor;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
var stage = new createjs.Stage('canvas');
|
||||||
|
|
||||||
|
// var shape = new createjs.Shape();
|
||||||
|
// shape.graphics.beginFill('red').drawRect(0, 0, 120, 120);
|
||||||
|
// stage.addChild(shape);
|
||||||
|
// stage.update();
|
||||||
|
|
||||||
|
var ss = new createjs.SpriteSheet({
|
||||||
|
frames: {
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
regX: 0,
|
||||||
|
regY: 0,
|
||||||
|
spacing: 0,
|
||||||
|
margin: 0,
|
||||||
|
count: 6
|
||||||
|
},
|
||||||
|
animations: {stand: 0, run: [0, 3]},
|
||||||
|
images: [document.querySelector("#creature-src")]
|
||||||
|
});
|
||||||
|
|
||||||
|
var sprite = new createjs.Sprite(ss, "stand");
|
||||||
|
sprite.scaleY = sprite.scaleX = 4;
|
||||||
|
stage.addChild(sprite);
|
||||||
|
|
||||||
|
sprite.on("click", function() { sprite.gotoAndPlay("jump"); });
|
||||||
|
|
||||||
|
createjs.Ticker.on("tick", stage);
|
@ -0,0 +1,123 @@
|
|||||||
|
// function prefixInputWithASpan(input, text){
|
||||||
|
// var span = document.createElement("span");
|
||||||
|
// span.innerText = text;
|
||||||
|
// input.parentElement.prepend(span);
|
||||||
|
// }
|
||||||
|
|
||||||
|
let terms;
|
||||||
|
let cParts = {};
|
||||||
|
|
||||||
|
function setupTextInput(key){
|
||||||
|
var input = document.getElementById(key + "Input");
|
||||||
|
prefixInputWithASpan(input, key)
|
||||||
|
input.setAttribute('min', 0);
|
||||||
|
input.setAttribute('max', terms[key].length - 1);
|
||||||
|
input.value = parseInt(Math.random() * (terms[key].length + 1));
|
||||||
|
var inputUpdate = function(e){
|
||||||
|
// gParts[key] = parseInt(e.target.value);
|
||||||
|
// console.log("INPUT UPDATE", e.target.value, gParts);
|
||||||
|
// updateOutCanvas();
|
||||||
|
console.log("INPUT UPDATE", e.target.value);
|
||||||
|
cParts[key] = parseInt(e.target.value);
|
||||||
|
updateCaption();
|
||||||
|
}
|
||||||
|
inputUpdate({ target: input });
|
||||||
|
input.onchange = inputUpdate;
|
||||||
|
input.oninput = inputUpdate;
|
||||||
|
};
|
||||||
|
|
||||||
|
let grammar = ["intro", "actor", "action", "prefix", "sort", "media"];
|
||||||
|
function updateCaption () {
|
||||||
|
let caption = "";
|
||||||
|
for (let gi=grammar.length-1; gi>=0; gi--) {
|
||||||
|
let key = grammar[gi];
|
||||||
|
let term = terms[key][cParts[key]];
|
||||||
|
if (!term) break;
|
||||||
|
console.log(`key: ${key}, term: ${term}`)
|
||||||
|
if (term.match(/a\(n\)/)) {
|
||||||
|
console.log(`doing a(n) replacement on ${term}, for [${caption}]`);
|
||||||
|
if (caption.match(/^[aeiou]/i)) {
|
||||||
|
console.log("VOWEL");
|
||||||
|
term = term.replace(/a\(n\)/, "an");
|
||||||
|
} else {
|
||||||
|
term = term.replace(/a\(n\)/, "a");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
caption = term + (caption?" ":"") + caption;
|
||||||
|
}
|
||||||
|
// grammar.forEach(key => {
|
||||||
|
// caption += (caption ? " " : "") + terms[key][cParts[key]];
|
||||||
|
// })
|
||||||
|
document.querySelector("#caption").innerHTML = caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function start () {
|
||||||
|
const src = document.querySelector("a#terms-data-source").href;
|
||||||
|
terms = await (await fetch(src)).json();
|
||||||
|
console.log("terms", terms);
|
||||||
|
setupTextInput("intro");
|
||||||
|
setupTextInput("action");
|
||||||
|
setupTextInput("actor");
|
||||||
|
setupTextInput("media");
|
||||||
|
setupTextInput("prefix");
|
||||||
|
setupTextInput("sort");
|
||||||
|
}
|
||||||
|
|
||||||
|
var randomizebtn = document.getElementById('randomizebtn');
|
||||||
|
randomizebtn.onclick = function() {
|
||||||
|
let inputs = document.getElementById('inputs').querySelectorAll('input.g');
|
||||||
|
|
||||||
|
for(var i=0; i<inputs.length; i++){
|
||||||
|
var input = inputs[i];
|
||||||
|
var key = input.id.replace("Input", "");
|
||||||
|
var max = PARTS_MAX[key];
|
||||||
|
var randval = Math.floor(Math.random() * (max + 1));
|
||||||
|
input.value = randval;
|
||||||
|
gParts[key] = randval;
|
||||||
|
if (key == 'color') {
|
||||||
|
// gColor = randval;
|
||||||
|
input.dispatchEvent(new Event('input', { 'bubbles': true }));
|
||||||
|
}
|
||||||
|
console.log("randomizing", input, randval);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOutCanvas();
|
||||||
|
|
||||||
|
inputs = document.getElementById('inputs').querySelectorAll('input.c');
|
||||||
|
for(var i=0; i<inputs.length; i++){
|
||||||
|
var input = inputs[i];
|
||||||
|
var key = input.id.replace("Input", "");
|
||||||
|
var max = terms[key].length;
|
||||||
|
var randval = Math.floor(Math.random() * (max + 0));
|
||||||
|
input.value = randval;
|
||||||
|
cParts[key] = randval;
|
||||||
|
}
|
||||||
|
updateCaption();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
|
function send (canvas, form) {
|
||||||
|
canvas.toBlob(blob => {
|
||||||
|
if (blob) {
|
||||||
|
const formdata = new FormData();
|
||||||
|
const filename = new Date().toISOString() + ".png";
|
||||||
|
formdata.append("image", blob, filename);
|
||||||
|
formdata.append("caption", document.querySelector("#caption").textContent);
|
||||||
|
formdata.append("message", form.message.value);
|
||||||
|
formdata.append("csrfmiddlewaretoken", form.csrfmiddlewaretoken.value);
|
||||||
|
fetch(form.action, { method:"POST", body: formdata })
|
||||||
|
.then(() => {
|
||||||
|
document.querySelector("#inputs").style.display = "none";
|
||||||
|
document.querySelector("#caption").disabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, "image/png");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector("button#send").addEventListener("click", () => {
|
||||||
|
console.log("SEND");
|
||||||
|
const form = document.querySelector("form");
|
||||||
|
send(outCanvas, form);
|
||||||
|
})
|
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang=en>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||||
|
<title>{% block title %}study at XPUB!{% endblock %}</title>
|
||||||
|
<style>{%block style %}{% endblock %}</style>
|
||||||
|
{%block extrahead %}{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{%block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,19 @@
|
|||||||
|
{% load static %}
|
||||||
|
<!doctype html>
|
||||||
|
<html lang=en>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||||
|
<title>xpub call 2025</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<img src="{{creature.image.url}}">
|
||||||
|
<p>{{creature.caption}}</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,6 @@
|
|||||||
|
{% extends "call/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<img src="{{object.image.url}}">
|
||||||
|
<p>{{object.caption}}</p>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,30 @@
|
|||||||
|
{% extends "call/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Creatures</h2>
|
||||||
|
<ul>
|
||||||
|
{% for creature in page_obj %}
|
||||||
|
<li><a href="{% url 'walk' creature.id %}">{{ creature.caption }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="pagination">
|
||||||
|
<span class="step-links">
|
||||||
|
{% if page_obj.has_previous %}
|
||||||
|
<a href="?page=1">« first</a>
|
||||||
|
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<span class="current">
|
||||||
|
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{% if page_obj.has_next %}
|
||||||
|
<a href="?page={{ page_obj.next_page_number }}">next</a>
|
||||||
|
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -0,0 +1,33 @@
|
|||||||
|
{% extends "call/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block extrahead %}
|
||||||
|
<link rel="stylesheet" href="{%static 'call/guestbook.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<marquee><h1>Welcome XPUB Class of 2025-2027</h1></marquee>
|
||||||
|
<div id="content">
|
||||||
|
{% for creature in page_obj %}
|
||||||
|
<img class="creature" src="{{creature.image.url}}" title="{{creature.caption}}">
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pagination">
|
||||||
|
<span class="step-links">
|
||||||
|
{% if page_obj.has_previous %}
|
||||||
|
<a href="?page=1">« first</a>
|
||||||
|
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<span class="current">
|
||||||
|
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{% if page_obj.has_next %}
|
||||||
|
<a href="?page={{ page_obj.next_page_number }}">next</a>
|
||||||
|
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="{% static 'call/guestbook.js' %}"></script>
|
||||||
|
{% endblock %}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,57 @@
|
|||||||
|
{% load static %}
|
||||||
|
{% block extrahead %}
|
||||||
|
<link rel="stylesheet" href="{% static 'call/statement.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<img src="{{creature.image.url}}" class="creature" style="display: none">
|
||||||
|
|
||||||
|
<canvas class="creature"></canvas>
|
||||||
|
<!-- <p>{{creature.caption}}</p> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <div class="bubble mini top">awesome!</div>
|
||||||
|
<div class="bubble right">I can get you a thumb by three o'clock</div>
|
||||||
|
<div class="bubble medium bottom">I'm not into the whole China thing, man</div>
|
||||||
|
<div class="bubble grow left">This is such a travesty</div>
|
||||||
|
<div class="bubble shadow large bottom">Ik moet nu eerst even een gerestaureerde drol hebben!</div> -->
|
||||||
|
|
||||||
|
<div class="bubble shadow large top"><textarea placeholder="Your messsage" autofocus id="caption"></textarea></div>
|
||||||
|
|
||||||
|
|
||||||
|
<p>The Master Experimental Publishing at the Piet Zwart Institute in Rotterdam (NL) is a two-year master focused on the acts of making things public and creating publics in the age of post-digital networks.</p>
|
||||||
|
<div id="info">
|
||||||
|
<p>Application deadlines:</p>
|
||||||
|
<p>
|
||||||
|
March 4, 2024 (non-EU + EU)<br>
|
||||||
|
May 8, 2024 (EU)<br>
|
||||||
|
</p>
|
||||||
|
<p>Open days:</p>
|
||||||
|
<p>
|
||||||
|
<a href="mailto:pzi.coordinators@hr.nl?subject=XPUB Open Day (online)&body=Hello, I will join the online open day on the February 6th on 10:00 CET or 16:00 CET" target="_blank">February 6, 2024</a> (online)<br>
|
||||||
|
<a href="https://www.pzwart.nl/blog/2023/10/10/open-day/" target="_blank">February 15, 2025</a> (IRL)<br>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<br>
|
||||||
|
<button id="apply">Apply</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>CSS Speech bubbles from <a href="https://codepen.io/josfabre/pen/EBMWwW">Jos Faber</a>.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Get canvas context
|
||||||
|
const ctx = document.querySelector("canvas.creature").getContext("2d");
|
||||||
|
|
||||||
|
// Load image
|
||||||
|
const image = new Image();
|
||||||
|
image.onload = () => {
|
||||||
|
// Draw the image into the canvas
|
||||||
|
ctx.drawImage(image, 0, 0, 64);
|
||||||
|
};
|
||||||
|
image.src = document.querySelector("img.creature").src;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -0,0 +1,14 @@
|
|||||||
|
{% extends "call/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block extrahead %}
|
||||||
|
<link rel="stylesheet" href="{% static 'call/walk.css' %}">
|
||||||
|
<script src="{% static 'EaselJS-1.0.0/lib/easeljs.js' %}"></script>
|
||||||
|
<script src="{% static 'TweenJS-1.0.0/lib/tweenjs.js' %}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{object}} {{object.image}} {{object.image.url}}
|
||||||
|
<div><img id="creature-src" src="{{object.image.url}}"></div>
|
||||||
|
<canvas id="canvas" width="550" height="250" style="border: 1px dotted gray"></canvas>
|
||||||
|
<script src="{% static 'call/walk.js' %}"></script>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
@ -0,0 +1,28 @@
|
|||||||
|
"""
|
||||||
|
URL configuration for call2025 project.
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/5.1/topics/http/urls/
|
||||||
|
Examples:
|
||||||
|
Function views
|
||||||
|
1. Add an import: from my_app import views
|
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||||
|
Class-based views
|
||||||
|
1. Add an import: from other_app.views import Home
|
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||||
|
Including another URLconf
|
||||||
|
1. Import the include() function: from django.urls import include, path
|
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
|
"""
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
from call import views
|
||||||
|
from .views import Guestbook, CreatureDetail, Statement, Walk
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("guestbook/", Guestbook.as_view(), name="guestbook"),
|
||||||
|
path("creatures/<int:pk>/", CreatureDetail.as_view(), name="creature_detail"),
|
||||||
|
path("creatures/<int:pk>/s/", Statement.as_view(), name="statement"),
|
||||||
|
path("creatures/<int:pk>/w/", Walk.as_view(), name="walk"),
|
||||||
|
path('', views.index)
|
||||||
|
]
|
@ -0,0 +1,41 @@
|
|||||||
|
from django.shortcuts import render, HttpResponseRedirect
|
||||||
|
from call.forms import CreatureForm
|
||||||
|
from django.views import generic
|
||||||
|
from .models import Creature
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
def index(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
print ("post", request.POST)
|
||||||
|
print ("files", request.FILES)
|
||||||
|
form = CreatureForm(request.POST, request.FILES)
|
||||||
|
# form = CreatureFormNo(request.POST, request.FILES)
|
||||||
|
# formset = AuthorFormSet(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
print ("FORM IS VALID")
|
||||||
|
form.save()
|
||||||
|
return HttpResponseRedirect(reverse("statement", args=(form.instance.id,)))
|
||||||
|
# do something.
|
||||||
|
else:
|
||||||
|
print ("FORM NOT VALID")
|
||||||
|
else:
|
||||||
|
form = CreatureForm()
|
||||||
|
return render(request, "call/index.html", {"form": form})
|
||||||
|
|
||||||
|
class Guestbook(generic.ListView):
|
||||||
|
paginate_by = 20
|
||||||
|
model=Creature
|
||||||
|
template_name = "call/guestbook.html"
|
||||||
|
|
||||||
|
class CreatureDetail(generic.DetailView):
|
||||||
|
model = Creature
|
||||||
|
|
||||||
|
class Statement(generic.DetailView):
|
||||||
|
model = Creature
|
||||||
|
template_name = "call/statement.html"
|
||||||
|
|
||||||
|
class Walk(generic.DetailView):
|
||||||
|
model = Creature
|
||||||
|
template_name = "call/walk.html"
|
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
ASGI config for call2025 project.
|
||||||
|
|
||||||
|
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'call2025.settings')
|
||||||
|
|
||||||
|
application = get_asgi_application()
|
@ -0,0 +1,131 @@
|
|||||||
|
"""
|
||||||
|
Django settings for call2025 project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 5.1.5.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = 'django-insecure-nn7mvrgu6de^%z&6t1usgaji_*59z*v+230tluec-h4fw*n(%i'
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = []
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'call',
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'call2025.urls'
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
'DIRS': [],
|
||||||
|
'APP_DIRS': True,
|
||||||
|
'OPTIONS': {
|
||||||
|
'context_processors': [
|
||||||
|
'django.template.context_processors.debug',
|
||||||
|
'django.template.context_processors.request',
|
||||||
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 'call2025.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': BASE_DIR / 'db' / 'db.sqlite3',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Password validation
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/5.1/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
# https://docs.djangoproject.com/en/5.1/howto/static-files/
|
||||||
|
|
||||||
|
# STATIC_URL = 'static/'
|
||||||
|
STATIC_URL = '/call/static/'
|
||||||
|
STATIC_ROOT = "/var/www/wsgi/call2025/static/"
|
||||||
|
|
||||||
|
# Default primary key field type
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
MEDIA_ROOT = 'media/'
|
||||||
|
MEDIA_ROOT = "/var/www/wsgi/call2025/media/"
|
||||||
|
MEDIA_URL = 'media/'
|
||||||
|
MEDIA_URL = '/call/media/'
|
@ -0,0 +1,138 @@
|
|||||||
|
"""
|
||||||
|
Django settings for call2025 project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 5.1.5.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = 'django-insecure-nn7mvrgu6de^%z&6t1usgaji_*59z*v+230tluec-h4fw*n(%i'
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = []
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'call',
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'call2025.urls'
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
'DIRS': [],
|
||||||
|
'APP_DIRS': True,
|
||||||
|
'OPTIONS': {
|
||||||
|
'context_processors': [
|
||||||
|
'django.template.context_processors.debug',
|
||||||
|
'django.template.context_processors.request',
|
||||||
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 'call2025.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': BASE_DIR / 'db' / 'db.sqlite3',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Password validation
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/5.1/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
# https://docs.djangoproject.com/en/5.1/howto/static-files/
|
||||||
|
|
||||||
|
#
|
||||||
|
DEPLOY = False
|
||||||
|
|
||||||
|
if DEPLOY:
|
||||||
|
STATIC_URL = '/call/static/'
|
||||||
|
STATIC_ROOT = "/var/www/wsgi/call2025/static/"
|
||||||
|
else:
|
||||||
|
STATIC_URL = 'static/'
|
||||||
|
|
||||||
|
# Default primary key field type
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
if DEPLOY:
|
||||||
|
MEDIA_URL = '/call/media/'
|
||||||
|
MEDIA_ROOT = "/var/www/wsgi/call2025/media/"
|
||||||
|
else:
|
||||||
|
MEDIA_ROOT = 'media/'
|
||||||
|
MEDIA_URL = 'media/'
|
@ -0,0 +1,26 @@
|
|||||||
|
"""
|
||||||
|
URL configuration for call2025 project.
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/5.1/topics/http/urls/
|
||||||
|
Examples:
|
||||||
|
Function views
|
||||||
|
1. Add an import: from my_app import views
|
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||||
|
Class-based views
|
||||||
|
1. Add an import: from other_app.views import Home
|
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||||
|
Including another URLconf
|
||||||
|
1. Import the include() function: from django.urls import include, path
|
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
|
"""
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('admin/', admin.site.urls),
|
||||||
|
path('', include('call.urls'))
|
||||||
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
WSGI config for call2025 project.
|
||||||
|
|
||||||
|
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'call2025.settings')
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
Binary file not shown.
After Width: | Height: | Size: 308 B |
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="2.8504503mm"
|
||||||
|
height="3.0193765mm"
|
||||||
|
viewBox="0 0 2.8504503 3.0193765"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||||
|
sodipodi:docname="corner.svg"
|
||||||
|
inkscape:export-filename="corner.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:zoom="32.494215"
|
||||||
|
inkscape:cx="7.7552266"
|
||||||
|
inkscape:cy="11.786713"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1008"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-47.887113,-41.55363)">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 48.027547,44.560578 v -2.60763 l 2.624924,2.60763"
|
||||||
|
id="path1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""Django's command-line utility for administrative tasks."""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run administrative tasks."""
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'call2025.settings')
|
||||||
|
try:
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
except ImportError as exc:
|
||||||
|
raise ImportError(
|
||||||
|
"Couldn't import Django. Are you sure it's installed and "
|
||||||
|
"available on your PYTHONPATH environment variable? Did you "
|
||||||
|
"forget to activate a virtual environment?"
|
||||||
|
) from exc
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue