Mattthew commited on
Commit
cabd7e6
1 Parent(s): ecf0e74

Upload 4 files

Browse files
Files changed (4) hide show
  1. artists_and_tags.js +557 -0
  2. index.css +722 -0
  3. index.html +196 -15
  4. index.js +1406 -0
artists_and_tags.js ADDED
@@ -0,0 +1,557 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var artistsData = [
2
+ ["Alma-Tadema","Lawrence","romanticism|victorian|history|opulent|ancient|opulent"],
3
+ ["Anatsui","El","abstract|sculpture|contemporary|African|recycled-materials|Ghanaian|textiles"],
4
+ ["Andersen","Sarah","cartoon|comics|high-contrast|contemporary|collage|femininity|fashion|mixed-media"],
5
+ ["Balfour","Ronald","art-deco|art-nouveau|watercolor|contemporary|vibrant|abstract|organic"],
6
+ ["Basquiat","Jean-Michel","expressionism|messy|neo-expressionism|street-art|African-American|graffiti|punk|contemporary"],
7
+ ["Beaux","Cecilia","impressionism|portraits|portraits|elegant|femininity|American"],
8
+ ["Blanche","John","fantasy|science-fiction|portraits|elegant|French"],
9
+ ["Bontecou","Lee","sculpture|abstract|contemporary|abstract|mixed-media"],
10
+ ["Burgert","Jonas","contemporary|figurative|surrealism|allegory|large-scale|German"],
11
+ ["Burlet","Richard","art-nouveau|impressionism|figurative|urban-life|characters|cityscapes|French"],
12
+ ["Cassatt","Mary","impressionism|characters|portraits|pastel"],
13
+ ["Cézanne","Paul","impressionism|cubism|romanticism|post-impressionism|still-life|landscapes|geometric"],
14
+ ["Chicago","Judy","abstract|vibrant|psychedelic|feminism|sculpture|installation|activism|femininity|empowerment"],
15
+ ["Ciurlionis","Mikalojus Konstantinas","dark|art-nouveau|symbolist|spirituality|Lithuanian|mysticism"],
16
+ ["Clark","Alson Skinner","landscapes|impressionism|impressionism|seascapes|atmospheric"],
17
+ ["Cowper","Frank Cadogan","Victorian|history|romanticism|British|opulent"],
18
+ ["Crewdson","Gregory","photography|surrealism|dark|eerie|suburbia|American"],
19
+ ["Davis","Stuart","cubism|abstract|social-realism|American|rural-life|printmaking"],
20
+ ["Dubbeldam","Ton","pointillism|landscapes|vibrant|contemporary|architecture|conceptual|geometric|Dutch"],
21
+ ["Earles","Amy","watercolor|characters|whimsical|dark|abstract-expressionism|gestural|American"],
22
+ ["Eliasson","Olafur","installation|contemporary|environmentalism|immersive|nature"],
23
+ ["Evans","Walker","photography|monochromatic|documentary|photography|American|great-depression|portraits|social-commentary"],
24
+ ["Fahrenkrog","Ludwig","expressionism|symbolist|mysticism|eerie|German"],
25
+ ["Flavin","Dan","installation|minimalism|light-art|sculpture|conceptual|sculpture|contemporary"],
26
+ ["Frankenthaler","Helen","abstract|expressionism|watercolor|abstract-expressionism|color-field|painting|feminism|printmaking|contemporary"],
27
+ ["Gascar","Henri","impressionism|landscapes|French|atmospheric"],
28
+ ["Goldberger","Sacha","photography|portraits|characters|contemporary|portraits|mixed-media|identity-exploration|immigrants"],
29
+ ["Gonzalez-Torres","Felix","installation|conceptual|installation|minimalism|LGBTQ|contemporary"],
30
+ ["Haacke","Hans","installation|photography|sculpture|conceptual|installation|environmentalism|politics|contemporary"],
31
+ ["Hammons","David","installation|abstract|conceptual|installation|African-American|social-commentary|contemporary"],
32
+ ["Haring","Keith","graffiti|street-art|expressionism|flat-colors|high-contrast|vibrant|pop-art|activism|LGBTQ"],
33
+ ["Hartley","Marsden","landscapes|portraits|primitivism|expressionism|modern|American|landscapes|abstract"],
34
+ ["Hassam","Childe","impressionism|cityscapes|American|landscapes|American|impressionism"],
35
+ ["Hatoum","Mona","installation|sculpture|photography|installation|conceptual|displacement|body-art|contemporary"],
36
+ ["Hawkes","Pam","figurativism|portraits|contemporary|ceramics|figurative|nature|organic|delicate"],
37
+ ["Heizer","Michael","installation|landscapes|angular|land-art|earthworks|nature|large-scale"],
38
+ ["Herrera","Carolina","photography|characters|fashion|minimalism|abstract|contemporary"],
39
+ ["Holler","Carsten","contemporary|immersive|interactive|experiential|playful"],
40
+ ["Huyghe","Pierre","conceptual|contemporary|conceptual|multimedia|surrealism"],
41
+ ["Irwin","Robert","installation|angular|minimalism|installation|environmentalism|contemporary"],
42
+ ["Judd","Donald","angular|installation|minimalism|sculpture|industrial-materials|contemporary"],
43
+ ["Kahlo","Frida","surrealism|portraits|vibrant|Mexican|self-portraits|feminism"],
44
+ ["Kelly","Ellsworth","abstract|flat-colors|minimalism|color-field|geometric|abstract|contemporary"],
45
+ ["Kentridge","William","messy|monochromatic|drawing|animation|printmaking|African|politics|contemporary"],
46
+ ["Koons","Jeff","sculpture|pop-art|vibrant|contemporary|kitsch|consumerism|post-modern"],
47
+ ["Krasner","Lee","expressionism|abstract|high-contrast|abstract-expressionism|color-field|gestural|improvisation|feminism"],
48
+ ["Kruger","Barbara","high-contrast|graphic-design|conceptual|feminism|text-based|montage|advertising|contemporary"],
49
+ ["Kusama","Yayoi","vibrant|polka-dots|installation|fashion|pop-art|contemporary|infinity-rooms|feminism|contemporary"],
50
+ ["Lawrence","Jacob","cubism|angular|modern|African-American|social-realism|harlem-renaissance|contemporary"],
51
+ ["Lawson","Ernest","impressionism|landscapes|everyday-life|American|American|impressionism"],
52
+ ["LeWitt","Sol","conceptual|minimalism|sculpture|geometric|abstract|wall-drawings|contemporary|serial-art"],
53
+ ["Lin","Maya","installation|land-art|architecture|identity-exploration|environmentalism|contemporary"],
54
+ ["List","Herbert","photography|monochromatic|high-contrast|surrealism|portraits|German"],
55
+ ["Mapplethorpe","Robert","photography|figure-studies|BDSM|monochromatic|portraits|homo-eroticism|LGBTQ"],
56
+ ["Martin","Agnes","minimalism|abstract-expressionism|grids|color-field|spirituality|contemporary"],
57
+ ["Merian","Maria Sibylla","biological|nature|naturalist|botanical|insects|observational"],
58
+ ["Metcalf","Willard","tonalism|landscapes|muted-colors|American"],
59
+ ["Morimoto","Kōji","contemporary|surrealism|illustration|Japanese|monsters|cute"],
60
+ ["Mostyn","Thomas Edwin","landscapes|still-life|portraits|romanticism|pre-raphaelite|landscapes|dream-like|British|mysticism"],
61
+ ["Murakami","Takashi","pop-art|manga-anime|flat-colors|Japanese|cute|contemporary"],
62
+ ["Nan","Juliana","contemporary|multimedia|identity-exploration|African"],
63
+ ["Nauman","Bruce","conceptual|sculpture|performance|neon|contemporary"],
64
+ ["Neel","Alice","high-contrast|portraits|expressionism|figurative|portraits|social-realism|feminism|contemporary"],
65
+ ["Neshat","Shirin","contemporary|video-art|photography|Iranian|feminism|identity-exploration"],
66
+ ["Noguchi","Isamu","sculpture|landscape-architecture|sculpture|organic|Japanese"],
67
+ ["O'Keeffe","Georgia","figurativism|abstract|watercolor|modern|precisionism|American|flowers|southwest|landscapes"],
68
+ ["Ofili","Chris","watercolor|expressionism|contemporary|figurative|painting|afro-futurism|mixed-media|post-colonialism"],
69
+ ["Parreno","Philippe","installation|contemporary|installation|multimedia|film|conceptual|post-modern"],
70
+ ["Perry","Lilla Cabot","impressionism|interiors|gardens|American"],
71
+ ["Ribemont-Dessaignes","Georges","Dadaism|avant-garde|French"],
72
+ ["Ringgold","Faith","pop-art|abstract|expressionism|feminism|quilting|African-American|activism|contemporary"],
73
+ ["Scully","Sean","abstract|angular|minimalism|grids"],
74
+ ["Serra","Richard","sculpture|installation|minimalism|large-scale|contemporary"],
75
+ ["Sherman","Cindy","photography|portraits|conceptual|photography|self-portraits|feminism|post-modern|identity-exploration|contemporary"],
76
+ ["Sims","David","contemporary|photography|fashion|British"],
77
+ ["Singer","Andy","pop-art|consumerism|celebrity|American"],
78
+ ["Smart","Jeffrey","surrealism|Scottish|dream-like"],
79
+ ["Smith","Kiki","minimalism|feminism|sculpture|body-art|performance|contemporary"],
80
+ ["Smithson","Robert","land-art|sculpture|conceptual|earthworks|environmentalism|post-minimalism"],
81
+ ["Suddese","Kate Van","contemporary|abstract|mixed-media|organic|vibrant"],
82
+ ["Sutherland","Graham","abstract|landscapes|expressionism|surrealism|portraits|distortion|British|battle-scenes|eerie"],
83
+ ["Tanning","Dorothea","surrealism|surrealism|dream-like|figure-studies|metamorphosis|eerie"],
84
+ ["Tenniel","John","kids-book|fantasy|whimsical|drawing"],
85
+ ["Thomson","Tom","expressionism|art-nouveau|impressionism|landscapes|Canadian|landscapes|nature|wilderness"],
86
+ ["Toth","Alex","cartoon|comics|high-contrast|figurative|animals|wildlife|bronze"],
87
+ ["Turrell","James","light-art|vibrant|installation|installation|sculpture|contemporary"],
88
+ ["Uhlig","Daniela","digital|portraits|characters|contemporary|landscapes|dream-like|ethereal|surrealism|German"],
89
+ ["Valadon","Suzanne","post-impressionism|nudes|mysterious"],
90
+ ["Valdi","Thiago","contemporary|urban-life|street-art|colorful|Brazilian"],
91
+ ["Varo","Remedios","surrealism|low-contrast|magical-realism|Spanish|surrealism"],
92
+ ["Vonnoh","Robert","impressionism|bronze|sculpture|American"],
93
+ ["Walker","Kara","silhouettes|African-American|identity-exploration|contemporary"],
94
+ ["Warhol","Andy","pop-art|vibrant|portraits|celebrity|contemporary"],
95
+ ["Weiwei","Ai","contemporary|installation|social-commentary|activism|politics|Chinese"],
96
+ ["Wiley","Kehinde","photorealism|portraits|vibrant|colorful|contemporary|portraits|African-American|baroque|identity-exploration"],
97
+ ["Wilson","Wes","contemporary|art-nouveau|psychedelic"],
98
+ ["Woodman","Francesca","feminism|self-portraits|photography|feminism|surrealism|still-life|contemporary"],
99
+ ["Wu","Bayard","fantasy|fashion|illustration|Chinese|LGBTQ|contemporary"],
100
+ ["Wylie","Rose","figurative|portraits|painting|observational|painting|contemporary"],
101
+ ["Abts","Tomma","abstract|angular|geometric|modern|minimalism|contemporary|color-field"],
102
+ ["Acconci","Vito","dark|installation|architecture|sculpture|performance|conceptual"],
103
+ ["Adams","Ansel","monochromatic|high-contrast|nature|American|landscapes|photography|landscapes|monochromatic"],
104
+ ["Aoshima","Chiho","pop-art|colorful|whimsical|manga-anime|fantasy|vibrant|Japanese|digital|futuristic"],
105
+ ["Araki","Hirohiko","manga-anime|Japanese|characters|pop-culture|illustration|manga-anime|graphic-novel|surrealism"],
106
+ ["Bacon","Francis","expressionism|British|portraits|abstract|dark|figurative|distortion|surrealism"],
107
+ ["Banksy","","street-art|graffiti|high-contrast|politics|social-commentary|anonymous|urban-life"],
108
+ ["Barney","Matthew","photography|surrealism|sculpture|video-art|performance|multimedia|film|conceptual"],
109
+ ["Bosch","Hieronymus","whimsical|renaissance|religion|mysticism|surrealism|allegory|religion|fantasy"],
110
+ ["Botticelli","Sandro","renaissance|Italian|figurative|mythology|religion|femininity|religion|dream-like"],
111
+ ["Chagall","Marc","fauvism|impressionism|surrealism|stained-glass|Russian|French|Jewish|colorful|folklore|romanticism"],
112
+ ["Constable","John","landscapes|romanticism|dark|nature|British|oil-painting|skies"],
113
+ ["Creed","Martin","installation|abstract|expressionism|minimalism|conceptual|British|playful|interactive"],
114
+ ["Crumb","Robert","comics|characters|American|underground|satire|underground|satire|counter-culture"],
115
+ ["Dalí","Salvador","surrealism|dark|Spanish|dream-like|oil-painting|dreams|illusion|metaphysics"],
116
+ ["Degas","Edgar","impressionism|French|ballet|pastel|drawing|portraits|dancers|femininity"],
117
+ ["Delacroix","Eugene","romanticism|French|history|oil-painting|sketching|orientalism|colorful|vibrant"],
118
+ ["Doig","Peter","figurativism|landscapes|abstract|British|Canadian|large-scale|dream-like|nature"],
119
+ ["Duchamp","Marcel","surrealism|cubism|fauvism|expressionism|impressionism|conceptual|dadaism"],
120
+ ["Ernst","Max","surrealism|expressionism|German|Dadaism|collage|oil-painting|automatism|mythology"],
121
+ ["Escher","M. C.","angular|high-contrast|surrealism|Dutch|lithography|woodblock-prints|geometric|illusion|mathematics"],
122
+ ["Freud","Lucian","portraits|expressionism|British|realism|oil-painting|figurative|flesh"],
123
+ ["Gaudi","Antoni","architecture|angular|Spanish|organic|mosaic|art-nouveau|fantasy"],
124
+ ["Gauguin","Paul","impressionism|primitivism|French|exoticism|oil-painting|colorful|tropics|spirituality"],
125
+ ["Giacometti","Alberto","sculpture|expressionism|Swiss|bronze|figurative|portraits|emaciation"],
126
+ ["Goya","Francisco","romanticism|portraits|Spanish|etching|social-commentary|oil-painting|dark|politics|satire|horror"],
127
+ ["Hiroshige","","ukiyo-e|landscapes|Japanese|woodblock-prints|nature|Edo-period|printmaking|Japanese"],
128
+ ["Hirst","Damien","conceptual|contemporary|installation|British|shock-art|mixed-media|sculpture|animals|death"],
129
+ ["Hockney","David","pools|cubism|vibrant|colorful|British|pop-art|portraits"],
130
+ ["Hokusai","Katsushika","ukiyo-e|high-contrast|Japanese|woodblock-prints|nature|Edo-period|waves|japanese"],
131
+ ["Hopper","Edward","impressionism|American|realism|architecture|landscapes|oil-painting|urban-life|solitude|loneliness|nostalgia"],
132
+ ["Horn","Roni","conceptual|sculpture|photography|American|minimalism|installation|nature|environmentalism"],
133
+ ["Kandinsky","Wassily","bauhaus|expressionism|abstract|vibrant|Russian|modern|spirituality"],
134
+ ["Klee","Paul","bauhaus|expressionism|abstract|surrealism|German|drawing|playful"],
135
+ ["Klein","William","photography|monochromatic|abstract|American|urban-life|fashion|minimalism"],
136
+ ["Klein","Yves","abstract|monochromatic|expressionism|French|performance|modern|color-field|fashion"],
137
+ ["Kleiner","Carl","abstract|surrealism|portraits|graphic-design|American|digital|collage|pop-art"],
138
+ ["Klimt","Gustav","art-nouveau|Austrian|erotica|mosaic|portraits|golden|female-figures"],
139
+ ["Larson","Gary","cartoon|American|newspaper|satire|pop-culture|comics|satire|animals|slice-of-life"],
140
+ ["Lichtenstein","Roy","comics|portraits|abstract|expressionism|American|pop-art"],
141
+ ["Magritte","Rene","surrealism|cloudscapes|art-deco|cubism|impressionism|Belgian|illusion"],
142
+ ["Manet","Édouard","impressionism|portraits|French|still-life|realism|femininity|modern-life|controversy"],
143
+ ["Matisse","Henri","fauvism|impressionism|French|collage|sculpture|color-field|colorful|cut-outs|decorative"],
144
+ ["Michelangelo","","renaissance|Italian|sculpture|frescoes|religion|figurative|ceiling-painting|religion"],
145
+ ["Miró","Joan","abstract|Spanish|surrealism|sculpture|drawing|color-field|colorful|outer-space|playful"],
146
+ ["Miyazaki","Hayao","whimsical|manga-anime|kids-book|Japanese|animation|fantasy|adventure"],
147
+ ["Modigliani","Amedeo","expressionism|fauvism|portraits|Italian|sculpture|modern|romanticism"],
148
+ ["Mondrian","Piet","cubism|vibrant|angular|Dutch|abstract|geometric|primary-colors|abstract"],
149
+ ["Monet","Claude","impressionism|landscapes|seascapes|French|plein-air|color-field|water-lilies"],
150
+ ["Morisot","Berthe","impressionism|feminism|landscapes|portraits|French|still-life|domestic-scenes|fleeting-moments"],
151
+ ["Moriyama","Daido","photography|Japanese|urban-life|monochromatic|post-war|documentary|grungy|urban-life"],
152
+ ["Mucha","Alphonse","art-nouveau|portraits|Czech|commercial-art|posters|decorative|femininity|decorative|stained-glass"],
153
+ ["Munch","Edvard","expressionism|impressionism|Norwegian|anxiety|oil-painting|dark|melancholy"],
154
+ ["Okamoto","Tarō","surrealism|gutai|Japanese|abstract|sculpture|avant-garde|performance"],
155
+ ["Picasso","Pablo","cubism|surrealism|impressionism|Spanish|sculpture|modern|collage|African-influence"],
156
+ ["Pollock","Jackson","abstract|messy|expressionism|American|drip-painting|action-painting"],
157
+ ["Potter","Beatrix","whimsical|watercolor|kids-book|British|animals|book-illustration|nature|animals"],
158
+ ["Renoir","Pierre-Auguste","impressionism|portraits|French|landscapes|plein-air|female-figures|pastel-colors|femininity|outdoor-scenes"],
159
+ ["Richter","Gerhard","abstract|German|photorealism|photography|oil-painting|contemporary|blurry|multimedia"],
160
+ ["Rijn","Rembrandt van","baroque|portraits|Dutch|etching|self-portraits|history|religion"],
161
+ ["Rothko","Mark","abstract|expressionism|American|color-field|large-scale|minimalism|spirituality"],
162
+ ["Rubens","Peter Paul","baroque|renaissance|romanticism|Flemish|history|painting|oil-painting|mythology|nudes"],
163
+ ["Schulz","Charles","comics|cartoon|American|characters|nostalgia|childhood|social-commentary"],
164
+ ["Shimamoto","Shozo","performance|gutai|Japanese|abstract|mixed-media|post-war|action-painting|collaborative"],
165
+ ["Spiegelman","Art","cartoon|comics|American|history|graphic-novel|autobiographical|Holocaust|animals"],
166
+ ["Strand","Paul","photography|monochromatic|American|photography|landscapes|portraits|abstract|minimalism|still-life|urban-life"],
167
+ ["Sugimoto","Hiroshi","photography|monochromatic|Japanese|conceptual|seascapes|long-exposure|architecture|geometric"],
168
+ ["Tezuka","Osamu","cartoon|manga-anime|Japanese|manga-anime|animation|characters|science-fiction|robots-cyborgs"],
169
+ ["Titian","","renaissance|dark|Italian|portraits|religion|oil-painting|mythology|mythology|painting|religion|colorful"],
170
+ ["Toulouse-Lautrec","Henri de","impressionism|art-nouveau|French|posters|lithography|portraits|nightlife|cabaret|bold-colors"],
171
+ ["Turner","J.M.W.","romanticism|landscapes|seascapes|British|watercolor|atmospheric"],
172
+ ["Utamaro","Kitagawa","ukiyo-e|Japanese|woodblock-prints|Edo-period|female-figures|nature|portraits|fashion|genre-scenes"],
173
+ ["Velázquez","Diego","baroque|Spanish|portraits|religion|oil-painting|realism|royalty|history|Spanish"],
174
+ ["Vermeer","Johannes","baroque|interiors|portraits|Dutch|genre-scenes|domestic-scenes|illusion"],
175
+ ["Ware","Chris","cartoon|comics|American|graphic-novel|modern-life|characters|slice-of-life"],
176
+ ["Watterson","Bill","friendship|American|characters|nostalgia|colorful"],
177
+ ["Whistler","James Abbott McNeill","whimsical|low-contrast|American|tonalism|portraits|etching|tonalism|interiors"],
178
+ ["Woodring","Jim","surrealism|comics|American|fantasy|characters|pen-and-ink|psychedelic|dream-like|aliens|creatures"],
179
+ ["Nielsen","Kay","Fantasy|Exoticism|fantasy|orientalism|Illustration|Graphic-design|Painting"],
180
+ ["Nesterov","Mikhail","Religion|Spirituality|religion|Figurative|Romanticism|Painting"],
181
+ ["Bloch","Albert","Satire|Social-commentary|Impressionism|Realism|Painting|Engraving"],
182
+ ["Kawase","Hasui","Plein-air|Slice-of-life|landscapes|ukiyo-e|Printmaking"],
183
+ ["Fontana","Franco","Conceptual|Metamorphosis|abstract|Spatialism|Painting|Sculpture"],
184
+ ["Stelfreeze","Brian","Activism|Social-realism|comics|Illustration|contemporary|digital"],
185
+ ["Hughes","Nicholas","Surreal|Symbolist|Realism|figurativism|Painting"],
186
+ ["Ditlev","Jan","Dreams|landscapes|Realism|Painting|Printmaking"],
187
+ ["Szukalski","Stanisław","Metaphysics|Mysticism|Surrealism|primitivism|Sculpture"],
188
+ ["Ancher","Helga","Observational|Slice-of-life|Realism|impressionism|Painting"],
189
+ ["MacDonald","Frances","Allegory|Nostalgia|landscapes|impressionism|Painting"],
190
+ ["Flint","Alex Russell","Social-commentary|Environmentalism|abstract|abstract-Expressionism|Painting|Illustration"],
191
+ ["Pasquini","Alice","Documentary|Social-realism|Public-Art|contemporary|Street-art|Mural-painting"],
192
+ ["Grimly","Gris","dark|comics|Whimsical|fantasy|Surrealism|Illustration"],
193
+ ["Smith","Samantha Keely","Dream-like|Loneliness|abstract|abstract-Expressionism|contemporary|Painting"],
194
+ ["Semenov","Anton","Surreal|Symbolist|Surrealism|shock-art|digital|Painting"],
195
+ ["Podolchak","Ihor","Metaphysics|Surrealism|underground|Film|Painting"],
196
+ ["Rousse","Georges","Femininity|Mysticism|Impressionism|Neo-Impressionism|Post-Impressionism|Painting"],
197
+ ["Vrubel","Mikhail","Symbolist|Religion|Painting|Sculpture"],
198
+ ["Biddle","George","politics|Activism|Impressionism|contemporary|Painting|Illustration"],
199
+ ["Pissarro","Camille","impressionism|Observational|Impressionism|Painting|Printmaking"],
200
+ ["Selimoglu","Niyazi","Exoticism|Futurism|Geometric|Orientalism|Painting|Printmaking"],
201
+ ["Sidibé","Malick","Documentary|Slice-of-life|Harlem-Renaissance|Photography"],
202
+ ["the Elder","Lucas Cranach","Religion|Allegory|religion|Renaissance|Painting"],
203
+ ["Manabe","Johji","Science-fiction|Metamorphosis|abstract|contemporary|Illustration"],
204
+ ["Tarnowski","Artur","Symbolist|Nostalgia|Realism|Romanticism|Painting"],
205
+ ["Garcin","Gilbert","Surreal|Conceptual|abstract|contemporary|Sculpture|Installation"],
206
+ ["Smilde","Berndnaut","Surreal|Metamorphosis|installation|installation|Installation|Photography"],
207
+ ["Ladrönn","José","Fantasy|Science-fiction|comics|comics|Illustration"],
208
+ ["Shatseva","Tanya","Russian|Surrealism|eerie|contemporary|Painting"],
209
+ ["Tessari","Vittorio","Satire|Social-commentary|abstract|Realism|Painting"],
210
+ ["Cruz-Diez","Carlos","Conceptual|illusion|Kinetic|Light-art"],
211
+ ["Bak","Karol","Conceptual|Metamorphosis|Impressionism|contemporary|Painting"],
212
+ ["Robinson","Charles","Satire|politics|Realism|Painting"],
213
+ ["Korovin","Konstantin","impressionism|Plein-air|Impressionism|Painting"],
214
+ ["Rattner","Abraham","expressionism|Symbolist|Expressionism|Painting|Sculpture"],
215
+ ["Hamilton","Richard","Pop-art|Consumerism|Pop-Art|Mixed-media"],
216
+ ["Toraji","","Commercial-art|Sculpture|Installation"],
217
+ ["Shinkai","Makoto","Slice-of-life|Fleeting-moments|manga-anime|contemporary|Film"],
218
+ ["Aldridge","Miles","Femininity|Consumerism|Pop-Art|Pop-art|Illustration"],
219
+ ["Rydingsvard","Ursula von","Metamorphosis|abstract|Minimalism|Sculpture"],
220
+ ["Whitaker","William","Documentary|Social-realism|landscapes|contemporary|Painting"],
221
+ ["Weissenbruch","Hendrik","Plein-air|Observational|landscapes|Painting"],
222
+ ["Wilkes","Cathy","Activism|Social-commentary|Surrealism|contemporary|Photography"],
223
+ ["Rocafort","Kenneth","illustration|Science-fiction|comics|Fantasy|contemporary|Illustration|Graphic-novel"],
224
+ ["Knight","Nick","Fantasy|Adventure|Surrealism|Pop-art|Illustration"],
225
+ ["Jensen","Georg","Symbolist|Plein-air|Realism|Painting"],
226
+ ["Hobbema","Meindert","Observational|Plein-air|landscapes|Dutch-Golden-Age|Painting"],
227
+ ["Khnopff","Fernand","Symbolist|metaphysics|Painting|Sculpture"],
228
+ ["Carte","Anto","Dream-like|Fantasy|abstract|contemporary|Painting"],
229
+ ["the Elder","Lorenzo Costa","Religion|Allegory|religion|Renaissance|Painting"],
230
+ ["Broom","Lee","Activism|Social-commentary|abstract|Harlem-Renaissance|Painting"],
231
+ ["the Elder","Jan van Kessel","Observational|Allegory|Still-Life|Nature|Baroque|Painting"],
232
+ ["Mendoza","Eddie","Consumerism|Commercial-art|urban-life|underground|Painting"],
233
+ ["Prendergast","Maurice","impressionism|Observational|Impressionism|Painting"],
234
+ ["Ohman","Jack","Satire|politics|comics|Illustration|contemporary|Painting"],
235
+ ["Killion","Tom","Plein-air|Observational|landscapes|contemporary|Printmaking"],
236
+ ["Roybal","Antonio","Social-realism|Slice-of-life|Social-Realism|contemporary|Painting"],
237
+ ["Solomon","Simeon","Symbolist|Metaphysics|abstract|contemporary|Painting"],
238
+ ["Thomas","Mickalene","Femininity|Identity-exploration|Collage|Portraits|contemporary|Painting|Photography"],
239
+ ["Ozeri","Yigal","Observational|Slice-of-life|Realism|contemporary|Painting"],
240
+ ["Picabia","Francis","Dadaism|Surreal|Dadaism|Surrealism|Painting"],
241
+ ["Aagaard","Zacharias Martin","Observational|Slice-of-life|landscapes|Romanticism|Painting"],
242
+ ["Tindle","David","Symbolist|Metaphysics|Surrealism|contemporary|Sculpture"],
243
+ ["Dossena","Emilio Giuseppe","Conceptual|metaphysics|abstract|contemporary|Sculpture"],
244
+ ["Ketner","Jeremiah","Activism|Social-commentary|abstract|contemporary|Painting"],
245
+ ["Lagorio","Lev","Plein-air|Observational|landscapes|Realism|Painting"],
246
+ ["Britenbucher","Renie","Fleeting-moments|Observational|Portraits|contemporary|Painting"],
247
+ ["Holloway","Zena","Photography|British|underwater|animals|portraits"],
248
+ ["Pinturicchio","","Painting|Renaissance|Religion|Allegory"],
249
+ ["Cold","Chris","Activism|Social-commentary|Land-Art|contemporary|Painting"],
250
+ ["Spriggs","Ian","Surreal|Symbolist|Illustration|contemporary|Painting"],
251
+ ["Marcela-Froideval","François","Fantasy|Science-fiction|contemporary|Graphic-novel"],
252
+ ["Caniglia","Jeremy","dark|Satire|Surrealism|contemporary|Painting"],
253
+ ["Nagy","Tibor","Symbolist|metaphysics|abstract|contemporary|Sculpture"],
254
+ ["Münter","Gabriele","expressionism|Symbolist|Expressionism|Painting"],
255
+ ["Fouquet","Jean","Religion|Allegory|Renaissance|renaissance|Painting"],
256
+ ["Gorky","Arshile","Surreal|Symbolist|abstract-Expressionism|Surrealism|Painting|Drawing"],
257
+ ["Raphael","","Renaissance|Painting"],
258
+ ["Ross","Bob","Commercial-art|Consumerism|landscapes|contemporary|Painting"],
259
+ ["Mosina","Inna","Femininity|Identity-exploration|Ballet|Photography|contemporary|Sculpture"],
260
+ ["Disney","Walt","Fantasy|Adventure|Cartoon|contemporary|Animation"],
261
+ ["Lasdun","Denys","Architecture|metaphysics|Architecture|contemporary"],
262
+ ["Ravesteyn","Jan van","Observational|Plein-air|Baroque|Architecture|Sculpture"],
263
+ ["HUSH","","Street-art|Activism|Painting"],
264
+ ["Heysen","Nora","Femininity|Consumerism|landscapes|contemporary|Painting"],
265
+ ["Fumito","Ueda","Dream-like|Surreal|video-games|contemporary|Video-art"],
266
+ ["Watts","James Thomas","Symbolist|Allegory|Victorian|Painting"],
267
+ ["Saarinen","Eero","Architecture|metaphysics|modern|Modern|Architecture"],
268
+ ["Fautrier","Jean","Metaphysics|abstract-expressionism|Painting|Sculpture"],
269
+ ["Davis","Jim","comics|Satire|comics|Illustration|contemporary"],
270
+ ["Taaffe","Philip","Surreal|Symbolist|abstract|contemporary|Painting"],
271
+ ["Permeke","Constant","expressionism|Symbolist|Expressionism|Painting|Sculpture"],
272
+ ["Qwek","Dom","Fantasy|Adventure|contemporary|Illustration"],
273
+ ["Solomon","Barbara Stauffacher","Pop-art|Commercial-art|Graphic-Design|contemporary|Graphic-design"],
274
+ ["Vivanco","Kelly","Femininity|Consumerism|Sculpture|contemporary|Photography"],
275
+ ["Grasso","Laurent","Surreal|Conceptual|Surrealism|contemporary|Sculpture"],
276
+ ["Francés","Victoria","expressionism|Metaphysics|abstract|contemporary|Painting"],
277
+ ["Fegredo","Duncan","Fantasy|Adventure|comics|contemporary|Illustration"],
278
+ ["Shwedoff","Yuri","Surreal|Fantasy|contemporary|Illustration"],
279
+ ["Nicholson","William","Observational|Slice-of-life|abstract|Modern|Painting"],
280
+ ["Cotton","Olive","Australian|Modern|photography"],
281
+ ["Clausen","George","Observational|Plein-air|Realism|Painting"],
282
+ ["Howitt","Alex","Fleeting-moments|Slice-of-life|Illustration|contemporary|Painting"],
283
+ ["Cormon","Fernand","impressionism|Observational|Realism|Painting"],
284
+ ["Sueur","Eustache Le","impressionism|Fleeting-moments|portraits|Baroque|Painting"],
285
+ ["Williams","Kyffin","Surreal|Symbolist|landscapes|contemporary|Painting"],
286
+ ["Hegarty","Valerie","Social-commentary|metamorphosis|sculpture|Painting"],
287
+ ["Telgemeier","Raina","autobiographical|Slice-of-life|comics|graphic-novel|contemporary|Graphic-novel"],
288
+ ["Mashkov","Ilya","expressionism|Symbolist|russian|painting"],
289
+ ["Steinlen","Théophile","Observational|Allegory|Art-Nouveau|Printmaking"],
290
+ ["Bissell","Robert","impressionism|Plein-air|Wildlife|contemporary|Painting"],
291
+ ["Lhote","André","Symbolist|impressionism|Cubism|Painting"],
292
+ ["Morris","Sarah","Femininity|Identity-exploration|abstract|contemporary|Painting"],
293
+ ["Truitt","Anne","minimalism|Conceptual|Minimalism|Sculpture"],
294
+ ["Launay","Melissa","Surreal|Symbolist|abstract|contemporary|Painting"],
295
+ ["Roy","Pierre","impressionism|Observational|abstract|contemporary|Painting"],
296
+ ["Jiaying","He","Femininity|Identity-exploration|Realism|contemporary|Painting"],
297
+ ["Achenbach","Andreas","Plein-air|Observational|landscapes|Romanticism|Painting"],
298
+ ["Barnet","Will","Activism|Social-commentary|abstract|contemporary|Painting"],
299
+ ["Bellotto","Bernardo","Observational|Plein-air|landscapes|Rococo|Painting"],
300
+ ["Bernini","Gian Lorenzo","Religion|Allegory|Baroque|Sculpture"],
301
+ ["Herriman","George","Satire|politics|comics|contemporary|Illustration"],
302
+ ["Wooten","Ben","Femininity|Identity-exploration|abstract|contemporary|Painting"],
303
+ ["Sudworth","Anne","Femininity|Metaphysics|landscapes|contemporary|Illustration"],
304
+ ["Belkina","Katerina","Femininity|Identity-exploration|portraits|contemporary|Photography"],
305
+ ["Parrish","Maxfield","Fantasy|Nostalgia|Art-Nouveau|Painting"],
306
+ ["Fleischer","Max","comics|dark|Animation|contemporary"],
307
+ ["Oshii","Mamoru","Science-fiction|Metaphysics|manga-anime|contemporary|Animation"],
308
+ ["Etchells","Tim","Conceptual|metaphysics|conceptual|contemporary|Painting"],
309
+ ["Mutu","Wangechi","Feminism|Identity-exploration|Collage|contemporary|Mixed-media"],
310
+ ["Chambers","Tom","Fleeting-moments|Observational|abstract|contemporary|Illustration"],
311
+ ["Maillol","Aristide","Surreal|metaphysics|modern|Art-Nouveau|Sculpture"],
312
+ ["the Younger","Hans Holbein","Anthropoformism|portraits|Renaissance|Painting"],
313
+ ["Werkman","H.N.","activism|Typography|Printmaking"],
314
+ ["Seliger","Mark","Anxiety|Metaphysics|Portraits|Photography|contemporary|Photography"],
315
+ ["Loughridge","Lee","autobiographical|Conceptual|abstract|contemporary|Illustration"],
316
+ ["Andreev","Alex","Death|Displacement|Surrealism|contemporary|Painting"],
317
+ ["Zerbe","Karl","Documentary|Dreams|Surrealism|Expressionism|Painting"],
318
+ ["Addams","Charles","Social-commentary|Cartoon|contemporary|Illustration"],
319
+ ["Castelfranco","Giorgio Barbarelli da","Environmentalism|Fantasy|Rococo|Renaissance|Painting"],
320
+ ["Fuke","Ryohei","Fleeting-moments|Identity-exploration|landscapes|contemporary|Painting"],
321
+ ["Gahō","Hashimoto","Kitsch|Politics|Printmaking|ukiyo-e"],
322
+ ["Bergland","Don","Religion|Social-realism|landscapes|contemporary|Photography"],
323
+ ["Manara","Milo","Controversy|Femininity|erotica|Comics|Illustration"],
324
+ ["Guanzhong","Wu","Feminism|Homo-eroticism|landscapes|contemporary|Illustration"],
325
+ ["Johns","Jasper","Dream-like|Mysticism|abstract-Expressionism|Painting|Printmaking"],
326
+ ["Kelsner","Alfred","Metamorphosis|Surreal|abstract|contemporary|Painting"],
327
+ ["Mulready","Augustus Edwin","Symbolist|Commercial-art|Realism|Romanticism|Painting"],
328
+ ["Moonan","John","Nostalgia|Slice-of-life|abstract|contemporary|Painting"],
329
+ ["Dauterman","Russell","Observational|Plein-air|comics|superheroes|contemporary|Illustration"],
330
+ ["Vogelsang","Elke","abstract|contemporary|Painting"],
331
+ ["Ledroit","Olivier","comics|Fantasy|fantasy|Illustration"],
332
+ ["Casson","A. J.","Mathematics|Punk|landscapes|contemporary|Painting"],
333
+ ["Gray","Eileen","Friendship|Loneliness|abstract|contemporary|Painting"],
334
+ ["Olsen","Greg","outer-space|Spirituality|Wildlife|contemporary|Painting"],
335
+ ["Jover","Loui","eerie|satire|Illustration|contemporary"],
336
+ ["Veeber","Kuno","Science-fiction|Exoticism|abstract|contemporary|Painting"],
337
+ ["Musgrove","Scott","Adventure|Advertising|landscapes|contemporary|Illustration"],
338
+ ["Munnings","Alfred","horses|modern|Painting"],
339
+ ["Abbott","Elenore","fantasy|watercolor|art-nouveau|dream-like|ethereal|romanticism|pastel-colors|femininity|mythology"],
340
+ ["Anderson","Richard","digital|fantasy|dark|messy|surreal|gothic|horror|psychedelic"],
341
+ ["Argyle","Steve","fantasy|characters|whimsical|colorful|cartoon|playful"],
342
+ ["Bagshaw","Tom","characters|dark|fantasy|surreal|horror|eerie|melancholy|dark"],
343
+ ["Balaskas","Christopher","vibrant|digital|landscapes|science-fiction|futuristic|eerie|outer-space"],
344
+ ["Bana","Benedick","characters|science-fiction|messy|monochromatic|3D-rendering|grungy|industrial|cyberpunk|dystopia"],
345
+ ["Barker","Cicely Mary","fantasy|whimsical|characters|folklore|magic|magic|nostalgia"],
346
+ ["Barlowe","Wayne","science-fiction|fantasy|dark|alien-worlds|alien-worlds|dystopia|mythology|creatures|eerie"],
347
+ ["Bautista","Chiara","fantasy|dark|whimsical|dream-like|mysterious|surreal|magic|illusion"],
348
+ ["Bean","Alan","science-fiction|outer-space|metaphysics|astronaut|painting"],
349
+ ["Becket-Griffith","Jasmine","fantasy|portraits|whimsical|vibrant|gothic|fairies|magic|romanticism"],
350
+ ["Bell","Julie","fantasy|nature|dragons|magic|mythology|magic|magic|wilderness"],
351
+ ["Bergsma","Jody","watercolor|fantasy|whimsical|fairies|mythology|dream-like|magical-realism|ethereal"],
352
+ ["Berkey","John","fantasy|science-fiction|eerie|outer-space|futuristic"],
353
+ ["Bilal","Enki","science-fiction|comics|cyberpunk|urban-life|grungy|futuristic|dystopia|surreal"],
354
+ ["Binkley","Ed","fantasy|mythology|dream-like|magic|ethereal|mythology|whimsical"],
355
+ ["Bogle","Lee","portraits|fantasy|surreal|dream-like|eerie|ethereal"],
356
+ ["Bonestell","Chesley","science-fiction|alien-worlds|outer-space|futuristic"],
357
+ ["Bosma","Sam","cartoon|comics|fantasy|characters|playful|whimsical|colorful|animation"],
358
+ ["Bosschart","Johfra","whimsical|fantasy|surreal|dream-like|magic|mythology|ethereal|dream-like"],
359
+ ["Boulet","Susan Seddon","fantasy|magical-realism|nature|whimsical|ethereal|magic|dream-like|femininity"],
360
+ ["Bowater","Charlie","fantasy|digital|portraits|characters|dark|gothic|eerie"],
361
+ ["Bradley","Noah","dark|landscapes|fantasy|eerie|dark|dark|eerie|eerie|eerie"],
362
+ ["Briclot","Aleksi","fantasy|dark|grungy|dystopia|horror|gothic"],
363
+ ["Brom","Gerald","dark|fantasy|horror|gothic|horror|dark|eerie|horror"],
364
+ ["Brooks","Mark","comics|fantasy|science-fiction"],
365
+ ["Brown","Patrick","fantasy|comics|colorful"],
366
+ ["Burdisio","Alejandro","digital|landscapes|fantasy|science-fiction|dark|atmospheric|eerie|magic|eerie"],
367
+ ["Burns","Jim","science-fiction|characters|cyberpunk|grungy|urban-life|dark|futuristic|dystopia|noir"],
368
+ ["Cai","Zhichao","fantasy|digital|whimsical|dream-like|magic|ethereal|surreal"],
369
+ ["Caldwell","Clyde","fantasy|science-fiction|mythology|female-figures|pulp"],
370
+ ["Callebaut","Vincent","architecture|science-fiction|3D-rendering|futuristic|surreal|fantasy|cyberpunk|utopia|dystopia"],
371
+ ["Canete","Eric","fantasy|characters|messy|ethereal|whimsical|vibrant"],
372
+ ["Carman","Bill","fantasy|pop-art|surrealism|colorful|whimsical|playful|vibrant|psychedelic"],
373
+ ["Chen","Bo","fantasy|magic|whimsical|dream-like|magic|ethereal|magic|illusion"],
374
+ ["Christensen","James C.","whimsical|fantasy|mythology|ethereal|mysterious|magic|dream-like"],
375
+ ["Clark","Amanda","fantasy|landscapes|characters|watercolor|dream-like|magic|whimsical|ethereal"],
376
+ ["Corben","Richard","science-fiction|horror|comics|dark|horror|dark|eerie|horror"],
377
+ ["Dean","Roger","landscapes|fantasy|science-fiction|magic|eerie|dream-like|ethereal"],
378
+ ["Deharme","Lise","fantasy|whimsical|dream-like|magic|ethereal|magic|dream-like|surreal"],
379
+ ["Dell'otto","Gabriele","comics|fantasy|colorful"],
380
+ ["Delort","Nicolas","monochromatic|fantasy|dark|gothic|horror|dark|eerie|labyrinths"],
381
+ ["Delville","Jean","fantasy|surrealism|dream-like|magic|metaphysics"],
382
+ ["Demizu","Posuka","manga-anime|fantasy|whimsical|colorful|playful|vibrant|adventure|contemporary|illustration"],
383
+ ["Deschambault","Martin","digital|landscapes|science-fiction|eerie|eerie|minimalism|atmospheric|mysterious|futuristic"],
384
+ ["Deschamps","Eric","fantasy|science-fiction|digital|surreal"],
385
+ ["Detmold","Charles Maurice","fantasy|watercolor|art-nouveau|ethereal|mythology|magic|opulent|dream-like"],
386
+ ["Detmold","Edward Julius","fantasy|watercolor|art-nouveau|ethereal|mythology|magic|opulent|dream-like"],
387
+ ["DiTerlizzi","Tony","fantasy|whimsical|magic|magic|magic|vibrant|playful"],
388
+ ["Dittmann","Anna","portraits|fantasy|digital|ethereal|dream-like|mysterious"],
389
+ ["Dorman","Dave","science-fiction|horror|fantasy|photorealism|dark|horror|dark"],
390
+ ["Drysdale","TJ","photography|fantasy|landscapes|magic|dream-like|ethereal|eerie|magic"],
391
+ ["Earle","Eyvind","magical-realism|magic-realism|fantasy|high-contrast|dream-like|whimsical|surreal|colorful"],
392
+ ["Easley","Jeff","fantasy"],
393
+ ["Edlin","Tyler","fantasy|digital|landscapes|dream-like|ethereal|magic|whimsical|magic|magic"],
394
+ ["Edmiston","Jason","fantasy|horror|characters|portraits|illustration|dark|eerie|monochromatic|ethereal"],
395
+ ["Edwards","Les","science-fiction|horror|fantasy|illustration|outer-space|creatures|dark|horror"],
396
+ ["Eggleton","Bob","science-fiction|fantasy|horror|illustration|aliens|landscapes|colorful|dream-like"],
397
+ ["Ejsing","Jesper","fantasy|illustration|characters|mythology|whimsical|magic|adventure"],
398
+ ["Ellger","Christine","fantasy|magical-realism|illustration|dream-like|folklore|ethereal|surreal"],
399
+ ["Ellis","Dean","science-fiction|vibrant|illustration|cyberpunk|futuristic|technology|neon"],
400
+ ["Elmore","Larry","fantasy|illustration|superheroes|fantasy|medieval|battle-scenes"],
401
+ ["Elorza","Joseba","photography|surrealism|collage|science-fiction|outer-space|dream-like|abstract"],
402
+ ["Elson","Peter","science-fiction|outer-space|illustration|space-ships|robots-cyborgs|futuristic"],
403
+ ["Emshwiller","Ed","science-fiction|illustration|outer-space|aliens|pulp|colorful"],
404
+ ["Eng","Kilian","digital|landscapes|science-fiction|fantasy|atmospheric"],
405
+ ["Engle","Jason A.","fantasy|science-fiction|dark|illustration|creatures|dark|dark"],
406
+ ["Fabry","Glenn","fantasy|science-fiction|comics|illustration|grungy|violence"],
407
+ ["Fairhurst","Andy","science-fiction|fantasy|horror|digital|illustration|eerie|horror"],
408
+ ["Falero","Luis Ricardo","figurativism|fantasy|nudes|painting|dream-like|romanticism|erotica"],
409
+ ["Fate","Vincent Di","science-fiction|fantasy|illustration|outer-space|eerie|futuristic|outer-space"],
410
+ ["Ferez","Andrew","surrealism|fantasy|illustration|dream-like|fragmentation|eerie"],
411
+ ["Finch","David","comics|fantasy|illustration|superheroes|grungy|noir"],
412
+ ["Finlay","Virgil","comics|science-fiction|fantasy|horror|dark|high-contrast|pulp|eerie"],
413
+ ["Finnstark","Anato","digital|fantasy|illustration|whimsical|magic|colorful|magic|playful"],
414
+ ["Fitzgerald","John Anster","fantasy|whimsical|illustration|folklore|pastel|magic"],
415
+ ["Foss","Chris","vibrant|science-fiction|outer-space|illustration|psychedelic|alien-worlds|psychedelic"],
416
+ ["Frazetta","Frank","fantasy|dark|illustration|barbarians|muscles"],
417
+ ["Freas","Kelly","science-fiction|fantasy|illustration|adventure|eerie|eerie|colorful"],
418
+ ["Froud","Brian","fantasy|dark|whimsical|illustration|fairies|mythology|magic|magic"],
419
+ ["Froud","Wendy","fantasy|dark|whimsical|illustration|fairies|mythology|magic|magic"],
420
+ ["Gaughan","Jack","science-fiction|vibrant|illustration|aliens|outer-space|colorful|alien-worlds"],
421
+ ["Gerard","Justin","fantasy|whimsical|illustration|dream-like|folklore|magic|magic"],
422
+ ["Giancola","Donato","fantasy|science-fiction|illustration|mythology|painting"],
423
+ ["Giger","H.R.","science-fiction|dark|monochromatic|painting|surreal|robots-cyborgs|horror"],
424
+ ["Giraud","Jean","comics|psychedelic|surrealism|fantasy|science-fiction|illustration|dream-like|psychedelic"],
425
+ ["Gonzalez","Josan","science-fiction|illustration|cyberpunk|futuristic|technology|grungy|atmospheric"],
426
+ ["Guay","Rebecca","watercolor|digital|fantasy|illustration|dream-like|ethereal|magic"],
427
+ ["Guidice","Rick","science-fiction|illustration|space-ships|outer-space|adventure"],
428
+ ["Gurney","James","fantasy|landscapes|illustration|realism|painting|atmospheric|magic"],
429
+ ["Gustafson","Scott","magic-realism|whimsical|kids-book|fantasy|illustration|playful|colorful"],
430
+ ["Hardy","David A.","landscapes|science-fiction|illustration|outer-space"],
431
+ ["Harris","John","dark|science-fiction|outer-space|messy|illustration|dark|dystopia|grungy"],
432
+ ["Hase","Ryohei","magical-realism|surrealism|fantasy|digital|illustration|dream-like|ethereal|mysterious"],
433
+ ["Hideyoshi","Lorenz","digital|science-fiction|illustration|cyberpunk|futuristic|dark|neon|dystopia"],
434
+ ["Hildebrandt","Brothers","fantasy|vibrant|illustration|superheroes|painting"],
435
+ ["Hong","Kuang","fantasy|digital|dark|illustration|mythology|dark|eerie"],
436
+ ["Horkey","Aaron","fantasy|comics|illustration|etching|decorative"],
437
+ ["Horley","Alex","fantasy|dark|characters|illustration|dark|dark|grungy|horror"],
438
+ ["Horsley","Ralph","science-fiction|fantasy|whimsical|vibrant|dark|high-contrast|colorful|monochromatic|geometric|angular"],
439
+ ["Howe","John","fantasy|dark|eerie|portraits|landscapes|nature|characters"],
440
+ ["Huang","Shilin","fantasy|characters|dream-like|mysterious|magic|mythology"],
441
+ ["Hughes","Edward Robert","romanticism|characters|fantasy|impressionism|whimsical|dream-like|ethereal|nostalgia"],
442
+ ["Hutter","Michael","surrealism|fantasy|science-fiction|dream-like|horror|surreal|eerie"],
443
+ ["Jansson","Alexander","fantasy|whimsical|dark|dream-like|mythology|surreal"],
444
+ ["Jean","James","fantasy|mythology|colorful|mysterious"],
445
+ ["Jia","Ruan","digital|portraits|fantasy|dark|colorful|futuristic|surreal"],
446
+ ["Jones","Jeffrey Catherine","fantasy|figurativism|realism"],
447
+ ["Jones","Peter Andrew","science-fiction|fantasy|futuristic|eerie|alien-worlds|outer-space"],
448
+ ["Jusko","Joe","comics|fantasy"],
449
+ ["Kaluta","M.W.","fantasy|whimsical|romanticism|nostalgia|victorian|dream-like|ethereal"],
450
+ ["Karcz","Michal","landscapes|fantasy|science-fiction|photography|futuristic|surreal|eerie"],
451
+ ["Katsuya","Terada","manga-anime|fantasy|portraits|colorful|magic"],
452
+ ["Kelly","Ken","fantasy|characters|mythology|vibrant|whimsical"],
453
+ ["Kikuchi","Hideyuki","horror|fantasy|manga-anime|dark|eerie|dark|eerie"],
454
+ ["Kirby","Jack","comics|science-fiction"],
455
+ ["Koike","Kazuo","manga-anime|comics|fantasy"],
456
+ ["Kon","Satoshi","whimsical|high-contrast|fantasy|manga-anime|surreal|dream-like"],
457
+ ["Kutsche","Michael K","characters|fantasy|dark|whimsical|dream-like|mysterious|mythology"],
458
+ ["Kuvshinov","Ilya","vibrant|digital|fantasy|manga-anime|dream-like|romanticism|ethereal|surreal"],
459
+ ["Lacoste","Raphael","fantasy|landscapes|dark|mysterious|atmospheric|eerie|dream-like"],
460
+ ["Langley","Clint","comics|fantasy|digital|dark|grungy|urban-life|dystopia|noir"],
461
+ ["Lecouffe-Deharme","Bastien","digital|dark|fantasy|characters|surreal|ethereal|magic"],
462
+ ["Lee","Alan","fantasy|romanticism|dream-like|nostalgia|mythology|whimsical|ethereal"],
463
+ ["Lehr","Paul","science-fiction|fantasy|vibrant|colorful|high-contrast|futuristic|eerie|surreal"],
464
+ ["Lewandowski","Mariusz","fantasy|surrealism|dark|dream-like|mysterious|eerie"],
465
+ ["Liefeld","Rob","comics|science-fiction|fantasy"],
466
+ ["Madureira","Joe","comics|fantasy"],
467
+ ["Maitz","Don","science-fiction|fantasy|eerie|futuristic|surreal"],
468
+ ["Maleev","Alex","comics|fantasy|high-contrast|dark|dark|noir"],
469
+ ["Maniak","Slawomir","fantasy|dark|surreal|dream-like|eerie|mysterious|dark"],
470
+ ["Manzanedo","Antonio J.","fantasy|dark|characters|mysterious|dark"],
471
+ ["Mars","Chris","surrealism|dark|fantasy|dream-like|eerie|eerie|abstract"],
472
+ ["Martinière","Stephan","science-fiction|fantasy|landscapes|dark|futuristic|surreal|atmospheric"],
473
+ ["Matthews","Rodney","fantasy|science-fiction|futuristic|eerie|colorful"],
474
+ ["Mattingly","David B.","science-fiction|fantasy|eerie|futuristic|surreal|vibrant"],
475
+ ["Mayhew","Mike","comics|fantasy|portraits"],
476
+ ["McCaffrey","Anne","dragons|fantasy|science-fiction|mythology|adventure|magic"],
477
+ ["McCall","Robert","science-fiction|outer-space|futuristic"],
478
+ ["McFarlane","Todd","comics|fantasy|dark"],
479
+ ["McKie","Angus","vibrant|science-fiction|fantasy|futuristic"],
480
+ ["McPharlin","Dan","science-fiction|vibrant|surrealism|abstract|dream-like|ethereal|magic"],
481
+ ["McQuarrie","Ralph","science-fiction|landscapes|eerie|futuristic"],
482
+ ["McQue","Ian","science-fiction|fantasy|messy|grungy|dark|grungy|surreal"],
483
+ ["Mead","Syd","science-fiction|abstract|angular|futuristic|minimalism|technology|modern"],
484
+ ["Minguez","Victor Adame","fantasy|characters|digital|colorful|whimsical|mysterious"],
485
+ ["Moebius","","comics|psychedelic|surrealism|fantasy|science-fiction|dream-like"],
486
+ ["Mohrbacher","Peter","surrealism|fantasy|dark|whimsical|dream-like|ethereal|mythology"],
487
+ ["Monge","Jean-Baptiste","dark|fantasy|surreal|eerie|mysterious|dark"],
488
+ ["Moore","Alan","comics|dark|science-fiction|horror|fantasy|vibrant|dystopia|grungy|noir"],
489
+ ["Moore","Chris","science-fiction|high-contrast|cyberpunk|dystopia|technology|futuristic"],
490
+ ["Moore","Tony","comics|horror|science-fiction|magic|gothic|eerie|mythology|magic"],
491
+ ["Mullins","Craig","dark|fantasy|surrealism|mythology|dream-like|horror"],
492
+ ["Mumford","Dan","digital|vibrant|fantasy|psychedelic|surrealism|colorful|dreams|psychedelic"],
493
+ ["Nasmith","Ted","fantasy|landscapes|ethereal|magic|mythology|atmospheric"],
494
+ ["Nauck","Todd","comics|characters|science-fiction|superheroes|adventure"],
495
+ ["Nerdrum","Odd","dark|characters|fantasy|figurative|melancholy"],
496
+ ["Nihei","Tsutomu","manga-anime|science-fiction|dark|monochromatic|cyberpunk|dystopia|industrial|alien-worlds"],
497
+ ["Nirasawa","Yasushi","fantasy|characters|dark|creatures|mythology|monsters"],
498
+ ["Nizovtsev","Victor","magical-realism|vibrant|whimsical|fantasy|magic|mysterious|dream-like|surreal"],
499
+ ["Norem","Earl","fantasy|dark|battle-scenes|mythology"],
500
+ ["Oakes","Terry","fantasy|science-fiction|magic|outer-space|colorful|adventure"],
501
+ ["Ohrai","Noriyoshi","fantasy|science-fiction|futuristic|impressionism"],
502
+ ["Okon","Marek","digital|science-fiction|dark|surreal|robots-cyborgs|horror|magic"],
503
+ ["Paick","James","digital|landscapes|fantasy|science-fiction|vibrant|ethereal|eerie|immersive"],
504
+ ["Parkes","Michael","magical-realism|fantasy|art-nouveau|dream-like|spirituality|ethereal"],
505
+ ["Parkinson","Keith","fantasy|mythology|whimsical"],
506
+ ["Pennington","Bruce","science-fiction|fantasy|vibrant|landscapes|futuristic|outer-space"],
507
+ ["Razell","Aliza","photography|fantasy|surrealism|dream-like|ethereal|eerie|conceptual"],
508
+ ["Rebelka","Jakub","surrealism|fantasy|dream-like|illusion"],
509
+ ["Rekunenko","Valentin","fantasy|surrealism|dream-like|whimsical"],
510
+ ["Rigney","Brad","fantasy|characters|dark|mythology|surreal"],
511
+ ["Rocha","Andreas","digital|landscapes|fantasy|dark|atmospheric"],
512
+ ["Różalski","Jakub","landscapes|fantasy|science-fiction|battle-scenes|steampunk|futuristic|dystopia"],
513
+ ["Ruas","Joao","dark|comics|characters|fantasy|gothic|noir|horror"],
514
+ ["Rutkowski","Greg","digital|landscapes|fantasy|dark|atmospheric|surreal|eerie|eerie"],
515
+ ["Shaw","Barclay","science-fiction|dark|angular|cyberpunk|futuristic|industrial|neon"],
516
+ ["Shirow","Masamune","manga-anime|cartoon|manga-anime|comics|characters|fantasy|science-fiction|robots-cyborgs"],
517
+ ["Simonetti","Marc","landscapes|digital|fantasy|dark|surreal|dream-like"],
518
+ ["Smith","Adrian","dark|fantasy|digital|characters|grungy|dark"],
519
+ ["Sorayama","Hajime","characters|science-fiction|robots-cyborgs|futuristic|erotica|technology"],
520
+ ["Sparth","","digital|fantasy|science-fiction|landscapes|futuristic|surreal|minimalism|abstract"],
521
+ ["Stålenhag","Simon","landscapes|digital|science-fiction|nostalgia|rural-life|futurism|suburbia|eerie"],
522
+ ["Staples","Greg","comics|fantasy|adventure|characters|colorful"],
523
+ ["Stokes","Anne","fantasy|dark|characters|whimsical|mysterious|gothic|eerie"],
524
+ ["Stout","William","dark|fantasy|mythology|gothic"],
525
+ ["Struzan","Drew","portraits|fantasy|science-fiction|nostalgia"],
526
+ ["Sum","Brian","science-fiction|digital|characters|cyberpunk|futuristic"],
527
+ ["Suuronen","Matti","architecture|photography|science-fiction|futuristic|minimalism|modern|eerie"],
528
+ ["Swanland","Raymond","fantasy|digital|dark|dark|eerie|atmospheric|dark"],
529
+ ["Theurer","Heather","fantasy|romanticism|renaissance|ethereal|erotica|mythology|dream-like|baroque"],
530
+ ["Thole","Karel","surrealism|dark|science-fiction|horror|dream-like|horror"],
531
+ ["Uno","Aquirax","surreal|metaphysics|contemporary|painting|fantasy|vibrant|portraits|dream-like|abstract"],
532
+ ["Urschel","Jan","dark|digital|landscapes|science-fiction|atmospheric|dark|dystopia"],
533
+ ["Vacher","Christophe","cloudscapes|landscapes|fantasy|magical-realism|ethereal|dream-like"],
534
+ ["Vess","Charles","fantasy|comics|magic|dream-like|mythology|whimsical|romanticism"],
535
+ ["Walotsky","Ron","science-fiction|fantasy|surreal|futuristic"],
536
+ ["Whelan","Michael","science-fiction|fantasy|dream-like|surreal|vibrant|eerie|outer-space|alien-worlds"],
537
+ ["White","Tim","science-fiction|fantasy|landscapes|atmospheric|immersive"],
538
+ ["Williams","Gilbert","fantasy|landscapes|whimsical|magic|nostalgia"],
539
+ ["Williamson","Al","comics|science-fiction|fantasy|adventure|mythology"],
540
+ ["Wong","Liam","photography|colorful|vibrant|science-fiction|futuristic|dystopia|urban-life"],
541
+ ["Woodroffe","Patrick","science-fiction|surrealism|dream-like|illusion|eerie|eerie"],
542
+ ["Zand","Amir","science-fiction|digital|vibrant|futuristic|robots-cyborgs|technology"],
543
+ ];
544
+
545
+ // first category must be 'important' and last must be 'other' or things won't work
546
+ // tag names cannot be 'image-item' or 'hidden' because well, this isn't coded that well, lol
547
+ var tagCategories = [
548
+ ['important'],
549
+ ['mediums',"3D-rendering","animation","architecture","assemblage","body-art","book-illustration","bronze","calligraphy","caricature","cartoon","ceiling-painting","ceramics","collage","comics","digital","drawing","earthworks","enamel","engraving","etching","experiential","film","frescoes","graffiti","graphic-design","graphic-novel","illuminated-manuscripts","illustration","immersive","industrial-materials","infinity-rooms","installation","interactive","jewelry","kinetic","land-art","landscape-architecture","light-art","lithography","manga-anime","mixed-media","montage","mosaic","multimedia","mural-painting","newspaper","oil-painting","painting","pastel","pen-and-ink","performance","photography","posters","printmaking","public-art","quilting","recycled-materials","sculpture","sketching","stained-glass","street-art","tapestry","textiles","typography","video-art","video-games","wall-drawings","watercolor","woodblock-prints"],
550
+ ['styles',"abstract","action-painting","African-influence","afro-futurism","angular","anthropoformism","atmospheric","blurry","bohemian","bold-colors","color-field","colorful","cute","cyberpunk","dark","decorative","delicate","drip-painting","eerie","elegant","ethereal","figurative","flat-colors","folk-art","fragmentation","futuristic","geometric","gestural","golden","gothic","grids","grungy","high-contrast","illusion","improvisation","industrial","kids-book","large-scale","long-exposure","low-contrast","opulent","magic-realism","Maximalism","melancholy","messy","miniature","monochromatic","muted-colors","mysterious","naturalist","neon","noir","observational","organic","pastel-colors","photorealism","pin-up","playful","polka-dots","precisionism","primary-colors","propaganda","psychedelic","pulp","Rococo","steampunk","text-based","vibrant","whimsical"],
551
+ ['themes',"activism","adventure","advertising","allegory","anxiety","autobiographical","childhood","commercial-art","conceptual","consumerism","controversy","death","displacement","distortion","documentary","dream-like","dreams","dystopia","empowerment","environmentalism","exoticism","fantasy","femininity","feminism","fleeting-moments","folklore","friendship","futurism","homo-eroticism","horror","identity-exploration","kitsch","loneliness","magic","mathematics","metamorphosis","metaphysics","mysticism","nightlife","nostalgia","observational","plein-air","politics","punk","religion","satire","science-fiction","slice-of-life","social-commentary","solitude","spirituality","surreal","symbolist","utopia"],
552
+ ['subjects',"alien-worlds","aliens","animals","ballet","barbarians","battle-scenes","BDSM","biological","botanical","cabaret","celebrity","characters","cityscapes","cloudscapes","contemporary-life","counter-culture","creatures","dancers","domestic-scenes","dragons","emaciation","erotica","everyday-life","fairies","fashion","female-figures","figure-studies","flesh","flowers","gardens","genre-scenes","great-depression","history","holocaust","horses","immigrants","insects","interiors","kabuki-yakusha-e","labyrinths","landscapes","modern-life","monsters","muscles","mythology","nature","nudes","outdoor-scenes","outer-space","plein-air","pools","pop-culture","portraits","robots-cyborgs","royalty","rural-life","seascapes","self-portraits","silhouettes","skies","Southwest","space-ships","still-life","suburbia","superheroes","technology","tropics","underwater","urban-life","violence","water-lilies","waves","wilderness","wildlife"],
553
+ ['movements',"abstract-expressionism","art-deco","art-Nouveau","automatism","avant-garde","baroque","bauhaus","collaborative","cubism","cut-outs","dadaism","Dutch-golden-age","earthworks","expressionism","fauvism","figurativism","gutai","harlem-renaissance","impressionism","magical-realism","minimalism","neo-expressionism","neo-impressionism","orientalism","pointillism","pop-art","post-colonialism","post-impressionism","post-minimalism","primitivism","realism","romanticism","serial-art","shock-art","social-realism","spatialism","surrealism","tonalism","underground"],
554
+ ['periods',"ancient","Ancient-Egyptian","Ancient-Greek","contemporary","Edo-period","medieval","modern","post-colonialism","post-modern","post-war","pre-raphaelite","renaissance","ukiyo-e","Victorian"],
555
+ ['identities',"African","African-American","Albanian","Algerian","American","Angolan","anonymous","Argentinean","Armenian","Asian","Australian","Austrian","Azerbaijani","Bahraini","Bangladeshi","Barbadian","Belarusian","Belgian","Bengali","Bosnian","Brazilian","British","Bulgarian","Cameroonian","Canadian","Catalan","Chilean","Chinese","Colombian","CostaRican","Croatian","Cuban","Cypriot","Czech","Dane","Dominican","Dutch","Ecuadorian","Egyptian","Emirati","Estonian","Ethiopian","European","Filipino","Finnish","Flemish","French","Georgian","German","Ghanaian","Greek","Guatemalan","Guyanese","Hungarian","Icelandic","Indian","Indonesian","Iranian","Iraqi","Irish","Islamic","Israeli","Italian","Jamaican","Japanese","Jewish","Kenyan","Latvian","Lebanese","LGBTQ","Libyan","Lithuanian","Luxembourger","Macedonian","Mexican","Moldovan","Mongol","Montenegrin","Moroccan","Namibian","Native-American","New-Zealander","Nigerian","Norwegian","Palestinian","Peruvian","Polish","Portuguese","PuertoRican","Qatari","Romanian","Russian","Saudi","Scottish","Serbian","Slovak","Slovenian","SouthAfrican","SouthKorean","Spanish","Sudanese","Swedish","Swiss","Syrian","Thai","Tunisian","Turkish","Ukrainian","Uruguayan","Venezuelan","Vietnamese","Yemeni"],
556
+ ['other']
557
+ ];
index.css ADDED
@@ -0,0 +1,722 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ html, body {
2
+ background-color: black;
3
+ color: #fff;
4
+ font-family: 'Poppins', sans-serif;
5
+ font-size: 16px;
6
+ margin: 0;
7
+ padding: 0;
8
+ height: 100%;
9
+ }
10
+
11
+ h3 {
12
+ margin: 5px;
13
+ }
14
+
15
+ h4 {
16
+ margin: 0px;
17
+ font-weight: normal;
18
+ text-align: center;
19
+ line-height: 150%;
20
+ }
21
+
22
+ #layout {
23
+ display: flex;
24
+ flex-direction: column;
25
+ height: 100%;
26
+ }
27
+
28
+ #rows {
29
+ display: flex;
30
+ flex-direction: row;
31
+ flex-grow: 1;
32
+ overflow: auto;
33
+ }
34
+
35
+ #toggles {
36
+ position: fixed;
37
+ top: 0;
38
+ left: 0;
39
+ width: calc(40% - 20px);
40
+ height: calc(100% - 80px);
41
+ display: flex;
42
+ flex-direction: column;
43
+ flex-wrap: wrap;
44
+ opacity: 1;
45
+ line-height: 140%;
46
+ padding: 20px;
47
+ overflow: auto;
48
+ transition: opacity 50ms 100ms linear;
49
+ }
50
+
51
+ #gutter {
52
+ position: fixed;
53
+ top: 0;
54
+ left: 40%;
55
+ width: 40px;
56
+ height: calc(100% - 40px);
57
+ flex-shrink: 0;
58
+ background: black;
59
+ background: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 80%);
60
+ border-right: 1px solid #222;
61
+ }
62
+
63
+ #image-container {
64
+ display: flex;
65
+ flex-direction: row;
66
+ flex-wrap: wrap;
67
+ align-items: flex-start;
68
+ justify-content: space-around;
69
+ margin-left: calc(40% + 40px);
70
+ margin-top: 20px;
71
+ margin-bottom: 20px;
72
+ width: 100%;
73
+ }
74
+
75
+ #alert {
76
+ position: fixed;
77
+ z-index: 1;
78
+ opacity: 0;
79
+ top: 10px;
80
+ right: -52px;
81
+ padding: 10px;
82
+ color: #00ffe6;
83
+ background-color: #008679;
84
+ border: 1px solid #00ffe6;
85
+ border-radius: 3px;
86
+ box-shadow: 0 5px 20px #0000007d;
87
+ }
88
+
89
+ #alert.show {
90
+ right: 12px;
91
+ opacity: 1;
92
+ transition: all 100ms ease-in;
93
+ }
94
+
95
+ footer {
96
+ flex-shrink: 0;
97
+ padding: 5px 10px;
98
+ text-align: center;
99
+ color: #aaa;
100
+ background-color: #222;
101
+ border-top: 1px solid black;
102
+ font-size: 10px;
103
+ }
104
+
105
+ footer.special {
106
+ color: #00ffe6;
107
+ background-color: #008679;
108
+ font-size: 14px;
109
+ }
110
+
111
+ footer > div {
112
+ position: relative;
113
+ opacity: 0.8;
114
+ }
115
+
116
+ footer a {
117
+ text-decoration: none;
118
+ color: #fff;
119
+ }
120
+
121
+ footer span strong {
122
+ font-weight: bold;
123
+ color: #fff;
124
+ }
125
+
126
+ footer #why {
127
+ font-weight: bold;
128
+ color: #fff;
129
+ }
130
+
131
+ #close_footer {
132
+ position: absolute;
133
+ top: 0;
134
+ right: 0;
135
+ }
136
+
137
+ footer #close_footer strong {
138
+ display: block;
139
+ background-color: #aaa;
140
+ color: #222;
141
+ border-radius: 40px;
142
+ line-height: 150%;
143
+ cursor: pointer;
144
+ }
145
+
146
+ footer.special #close_footer strong {
147
+ background-color: #00ffe6;
148
+ color: #008679;
149
+ }
150
+
151
+ #layout.footerHidden #toggles {
152
+ height: calc(100% - 40px);
153
+ }
154
+
155
+ #layout.footerHidden #gutter {
156
+ height: calc(100%);
157
+ }
158
+
159
+ #layout.footerHidden footer {
160
+ display: none;
161
+ }
162
+
163
+ .divider {
164
+ border-bottom: 1px solid #333;
165
+ margin: 10px 40px 5px 0;
166
+ }
167
+
168
+ #toggles.hide {
169
+ opacity: 0;
170
+ transition: opacity 50ms linear;
171
+ }
172
+
173
+ #options_info,
174
+ #options_prompts,
175
+ #options_artist_sort,
176
+ #options_tag_sort {
177
+ margin-right: 10px;
178
+ }
179
+
180
+ #options_info > span:first-child,
181
+ #options_prompts > span:first-child,
182
+ #options_artist_sort > span:first-child,
183
+ #options_tag_sort > span:first-child {
184
+ margin-left: 21px;
185
+ }
186
+
187
+ #toggles label {
188
+ margin: 0 20px 0 0;
189
+ white-space: nowrap;
190
+ opacity: 0.8;
191
+ cursor: pointer;
192
+ }
193
+
194
+ #toggles label:hover {
195
+ opacity: 1;
196
+ }
197
+
198
+ #toggles #artistsShown {
199
+ margin: 0 0 0 21px;
200
+ white-space: nowrap;
201
+ position: relative;
202
+ top: 1px;
203
+ color: #ffe300;
204
+ opacity: 0.8;
205
+ }
206
+
207
+ #toggles label.top_all {
208
+ font-weight: bold;
209
+ }
210
+
211
+ #toggles label.top_control {
212
+ color: #ffe300;
213
+ }
214
+
215
+ #toggles label.top_control.warning {
216
+ color: #ff0000;
217
+ }
218
+
219
+ #toggles label.no_matches {
220
+ opacity: 0.3;
221
+ cursor: default;
222
+ }
223
+
224
+ #toggles label.category {
225
+ color: #00d5c0;
226
+ font-weight: bold;
227
+ padding-bottom: 5px;
228
+ margin: 10px 40px 0 0;
229
+ border-bottom: 1px solid #333;
230
+ }
231
+
232
+ #toggles label.hidden {
233
+ display: none;
234
+ }
235
+
236
+ #toggles label .most_used_indicator {
237
+ display: inline-block;
238
+ width: 14px;
239
+ height: 14px;
240
+ visibility: hidden;
241
+ margin-right: -14px;
242
+ position: relative;
243
+ top: 1px;
244
+ left: 4px;
245
+ color: #ffe300;
246
+ font-style: normal;
247
+ }
248
+
249
+
250
+
251
+ #toggles #artistsMatching {
252
+ opacity: 0.8;
253
+ cursor: default;
254
+ }
255
+
256
+ #toggles .count {
257
+ opacity: 0.5;
258
+ }
259
+
260
+ #toggles .link {
261
+ display: inline-block;
262
+ width: 20px;
263
+ height: 20px;
264
+ opacity: 0.7;
265
+ cursor: pointer;
266
+ box-sizing: border-box;
267
+ margin-left: 5px;
268
+ padding-left: 2px;
269
+ border-radius: 4px;
270
+ line-height: 130%;
271
+ }
272
+
273
+ #toggles .link.selected {
274
+ background-color: #444;
275
+ opacity: 1;
276
+ cursor: default;
277
+ }
278
+
279
+ #toggles .link:hover {
280
+ opacity: 1;
281
+ }
282
+
283
+ #toggles .link:hover::after {
284
+ position: absolute;
285
+ top: 20px;
286
+ left: 20px;
287
+ background-color: black;
288
+ padding: 0px 4px;
289
+ border: 1px solid #777;
290
+ border-radius: 3px;
291
+ color: #ddd;
292
+ box-shadow: 0 5px 10px black;
293
+ }
294
+
295
+ #infoI:hover::after {
296
+ content: 'instructions';
297
+ }
298
+
299
+ #infoA:hover::after {
300
+ content: 'about';
301
+ }
302
+
303
+ #infoX:hover::after {
304
+ content: 'export';
305
+ }
306
+
307
+ #promptA:hover::after {
308
+ content: 'artwork';
309
+ }
310
+
311
+ #promptP:hover::after {
312
+ content: 'portraits';
313
+ }
314
+
315
+ #promptL:hover::after {
316
+ content: 'landscapes';
317
+ }
318
+
319
+ #sortAA:hover::after {
320
+ content: 'alpha';
321
+ }
322
+
323
+ #sortAR:hover::after {
324
+ content: 'random';
325
+ }
326
+
327
+ #sortTA:hover::after {
328
+ content: 'alpha';
329
+ }
330
+
331
+ #sortTC:hover::after {
332
+ content: 'count';
333
+ }
334
+
335
+ .information {
336
+ display: none;
337
+ z-index: 2;
338
+ position: fixed;
339
+ top: 20px;
340
+ left: 20px;
341
+ width: calc(40% - 40px);
342
+ max-height: calc(100% - 110px);
343
+ padding: 20px;
344
+ overflow: auto;
345
+ background-color: #222;
346
+ border-radius: 2px;
347
+ border: 1px solid black;
348
+ box-shadow: 0 1px 0px #ffffff3d;
349
+ }
350
+
351
+ .information div {
352
+ opacity: 0.8;
353
+ }
354
+
355
+ .information h2, .information h3, .information ul{
356
+ margin-top: 0;
357
+ margin-left: 0;
358
+ }
359
+
360
+ .information h3 {
361
+ margin-bottom: 10px;
362
+ }
363
+
364
+ .information a {
365
+ color: #00ffe7;
366
+ font-weight: bold;
367
+ text-decoration: none;
368
+ }
369
+
370
+
371
+ .information a:hover {
372
+ color: #fff;
373
+ }
374
+
375
+
376
+ .information.shown {
377
+ display: block;
378
+ }
379
+
380
+ #instructions {
381
+ }
382
+
383
+ #about {
384
+
385
+ }
386
+
387
+ #export textarea {
388
+ resize: vertical;
389
+ width: 100%;
390
+ height: 200px;
391
+ }
392
+
393
+ #export .buttons {
394
+ display: flex;
395
+ flex-direction: row;
396
+ }
397
+
398
+ #export .buttons div {
399
+ cursor: pointer;
400
+ opacity: 0.8;
401
+ padding: 10px;
402
+ }
403
+
404
+ #export .buttons div:hover {
405
+ opacity: 1;
406
+ }
407
+
408
+ #filtersHidingAll {
409
+ display: none;
410
+ font-size: 24px;
411
+ color: #444;
412
+ text-align: center;
413
+ font-weight: bold;
414
+ position: relative;
415
+ top: 50%;
416
+ transform: translate(0%, -50%);
417
+ margin: 0 40px;
418
+ line-height: 220%;
419
+ }
420
+
421
+ #filtersHidingAll.shown {
422
+ display: block;
423
+ }
424
+
425
+ .image-item {
426
+ position: relative;
427
+ display: flex;
428
+ flex-direction: column;
429
+ align-items: center;
430
+ padding: 10px;
431
+ width: 256px;
432
+ background-color: #222;
433
+ border-radius: 2px;
434
+ margin: 0 5px 20px 5px;
435
+ box-shadow: 0 1px 0px #ffffff3d;
436
+ border: 1px solid black;
437
+ overflow: hidden;
438
+ }
439
+
440
+ .image-item.hidden {
441
+ display: none;
442
+ }
443
+
444
+ .image-item > span {
445
+ height: 84px;
446
+ position: relative;
447
+ display: block;
448
+ width: 100%;
449
+ }
450
+
451
+ .image-item h3 {
452
+ display: flex;
453
+ justify-content: center;
454
+ opacity: 0.8;
455
+ cursor: pointer;
456
+ height: 22px;
457
+ }
458
+
459
+ .image-item h4 {
460
+ width: 258px;
461
+ height: 52px;
462
+ opacity: 0.5;
463
+ cursor: pointer;
464
+ overflow: hidden;
465
+ position: absolute;
466
+ left: -1px;
467
+ padding-bottom: 6px;
468
+ box-sizing: border-box;
469
+ }
470
+
471
+ .image-item h3:hover {
472
+ opacity: 1;
473
+ }
474
+
475
+ .image-item h4:hover {
476
+ z-index: 1;
477
+ height: initial;
478
+ opacity: 1;
479
+ background-color: #222;
480
+ border-bottom: 1px solid #111;
481
+ color: #888;
482
+ }
483
+
484
+ .image-item .firstN {
485
+ margin-right: 8px;
486
+ white-space: nowrap;
487
+ }
488
+
489
+ .image-item .lastN {
490
+ white-space: nowrap;
491
+ }
492
+
493
+ .image-item > div {
494
+ width: 256px;
495
+ height: 256px;
496
+ text-align: center;
497
+ border: 1px solid black;
498
+ border-radius: 2px;
499
+ overflow: hidden;
500
+ }
501
+
502
+ .image-item .imgTools {
503
+ display: flex;
504
+ flex-direction: row;
505
+ align-items: end;
506
+ height: 100%;
507
+ background-color: #666;
508
+ opacity: 0.8;
509
+ }
510
+
511
+ .image-item .imgTools:hover {
512
+ opacity: 1;
513
+ }
514
+
515
+ .image-item .imgTools > div {
516
+ position: relative;
517
+ opacity: 0.7;
518
+ cursor: pointer;
519
+ }
520
+
521
+ .image-item .imgTools > div:hover {
522
+ opacity: 1;
523
+ }
524
+
525
+ .image-item .imgTools span {
526
+ position: absolute;
527
+ display: block;
528
+ width: 24px;
529
+ height: 24px;
530
+ border-radius: 4px;
531
+ top: 50%;
532
+ left: 50%;
533
+ transform: translate(-50%, -50%);
534
+ box-sizing: border-box;
535
+ background-color: #545454;
536
+ box-shadow: 0 0 5px #777
537
+ }
538
+
539
+ .image-item .art_prev {
540
+ width: 50px;
541
+ height: 50px;
542
+ background-color: #333;
543
+ border-radius: 0px 4px 0px 0px;
544
+ }
545
+
546
+ .image-item .art_next {
547
+ width: 50px;
548
+ height: 50px;
549
+ background-color: #333;
550
+ border-radius: 4px 0px 0px 0px;
551
+ }
552
+
553
+ .image-item .art_star {
554
+ flex-grow: 1;
555
+ width: 128px;
556
+ height: 100%;
557
+ }
558
+
559
+ .image-item .art_star span {
560
+ font-size: 48px;
561
+ width: 60px;
562
+ height: 60px;
563
+ line-height: 120%;
564
+ padding: 0;
565
+ filter: grayscale(100%);
566
+ background-color: initial;
567
+ box-shadow: none;
568
+ }
569
+
570
+ .image-item .imgBox {
571
+ position: relative;
572
+ z-index: 0;
573
+ top: -256px;
574
+ left: 0px;
575
+ width: 256px;
576
+ aspect-ratio: 1 / 1;
577
+ overflow: hidden;
578
+ border-radius: 2px;
579
+ background-color: #222;
580
+ cursor: pointer;
581
+ animation-name: reduce;
582
+ animation-duration: 100ms;
583
+ animation-timing-function: linear;
584
+ animation-iteration-count: 1;
585
+ animation-direction: forward;
586
+ }
587
+
588
+ .image-item:hover .imgBox {
589
+ position: fixed;
590
+ z-index: 1;
591
+ top: 0px;
592
+ left: 20px;
593
+ width: 40%;
594
+ cursor: not-allowed;
595
+ transform: translateY(20px);
596
+ animation-name: enlarge;
597
+ animation-duration: 100ms;
598
+ animation-timing-function: east-out;
599
+ animation-iteration-count: 1;
600
+ animation-direction: forward;
601
+ }
602
+
603
+ @keyframes enlarge {
604
+ 0% {
605
+ opacity: 0;
606
+ transform: translateY(0px);
607
+ }
608
+ 100% {
609
+ opacity: 1;
610
+ transform: translateY(20px);
611
+ }
612
+ }
613
+
614
+ @keyframes reduce {
615
+ 0% {
616
+ opacity: 0;
617
+ }
618
+ 100% {
619
+ opacity: 1;
620
+ }
621
+ }
622
+
623
+ .image-item img {
624
+ display: block;
625
+ width: 256px;
626
+ }
627
+
628
+ .image-item img.hidden {
629
+ display: none;
630
+ }
631
+
632
+ .image-item:hover .imgBox img {
633
+ width: 100%;
634
+ }
635
+
636
+ .image-item.favorite {
637
+ border: 1px solid #ffc10080;
638
+ box-shadow: 0 0px 15px #ffe20045;
639
+ }
640
+
641
+ .image-item.favorite .art_star span {
642
+ filter: grayscale(0%);
643
+ }
644
+
645
+ #layout.edit_mode #toggles {
646
+ width: calc(100% - 40px);
647
+ transition: width 200ms ease-out;
648
+ }
649
+
650
+ #layout.edit_mode #gutter {
651
+ left: calc(100% - 40px);
652
+ transition: left 200ms ease-out;
653
+ }
654
+
655
+ #layout.edit_mode #image-container {
656
+ opacity: 0.2;
657
+ margin-left: 100%;
658
+ overflow: hidden;
659
+ transition: width 200ms ease-out;
660
+ }
661
+
662
+ #edit_most_used {
663
+ color: #ffe300;
664
+ opacity: 0.8;
665
+ cursor: pointer;
666
+ margin: 5px 0 0 21px;
667
+ }
668
+
669
+ #edit_most_used:hover {
670
+ opacity: 1;
671
+ }
672
+
673
+ #edit_most_used.hidden {
674
+ display: none;
675
+ }
676
+
677
+ #layout.edit_mode #edit_most_used {
678
+ font-weight: bold;
679
+ color: #ff0000;
680
+ }
681
+
682
+ #layout.edit_mode .top_control,
683
+ #layout.edit_mode .divider,
684
+ #layout.edit_mode #options_prompts,
685
+ #layout.edit_mode #options_tag_sort,
686
+ #layout.edit_mode #options_artist_sort,
687
+ #layout.edit_mode #options_info,
688
+ #layout.edit_mode .category .count {
689
+ visibility: hidden;
690
+ }
691
+
692
+ #layout.edit_mode .category {
693
+ color: #fff;
694
+ opacity: 0.5;
695
+ }
696
+
697
+ #layout.edit_mode .category:hover {
698
+ cursor: default;
699
+ opacity: 0.5;
700
+ }
701
+
702
+ #layout.edit_mode [data-category-name="important"] {
703
+ opacity: 1;
704
+ color: #ffe300;
705
+ }
706
+
707
+ #layout.edit_mode [data-category-name="important"]:hover {
708
+ opacity: 1;
709
+ }
710
+
711
+ #layout.edit_mode #toggles .was_moved {
712
+ font-weight: bold;
713
+ color: #ffe300;
714
+ }
715
+
716
+ #layout.edit_mode #toggles input {
717
+ visibility: hidden;
718
+ }
719
+
720
+ #layout.edit_mode #toggles .most_used_indicator {
721
+ visibility: visible;
722
+ }
index.html CHANGED
@@ -1,19 +1,200 @@
1
  <!DOCTYPE html>
2
  <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  </div>
 
 
 
 
 
 
 
 
 
 
18
  </body>
19
- </html>
 
1
  <!DOCTYPE html>
2
  <html>
3
+ <head>
4
+ <script type="text/javascript" src="artists_and_tags.js"></script>
5
+ <script type="text/javascript" src="index.js"></script>
6
+ <link rel="stylesheet" href="index.css">
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
10
+ </head>
11
+ <body>
12
+ <div id="layout">
13
+ <div id="rows">
14
+ <div id="instructions" class="information">
15
+ <div>
16
+ <h2>How to</h2>
17
+ <h3>Clicking an artist's...</h3>
18
+ <ul>
19
+ <li><strong>name</strong> copies them to clipboard</li>
20
+ <li><strong>tags</strong> toggles those checkmarks</li>
21
+ <li><strong>star</strong> marks them as favorite</li>
22
+ <li>🎨, 🧑, and 🏞️ switches the prompt/image</li>
23
+ </ul>
24
+ <h3>Permissive filter</h3>
25
+ <ul>
26
+ <li><strong>checked:</strong> artists matching <strong>any</strong> checked tags</li>
27
+ <li><strong>unchecked:</strong> artists matching <strong>all</strong> checked tags</li>
28
+ <li>use unchecked to filter your favorites</li>
29
+ </ul>
30
+ <h3>Hide low-use tags</h3>
31
+ <ul>
32
+ <li><strong>checked:</strong> hides tags that match less than 3 artists</li>
33
+ <li>note that all hidden tags are unchecked</li>
34
+ </ul>
35
+ <h3>When using Stable Diffusion</h3>
36
+ <ul>
37
+ <li>Reproduce these styles with the prompt with "by {Artist full name}, ...."
38
+ <li>Adding the style tags to the prompt can also help</li>
39
+ <li>You can combine the styles of two are more artists</li>
40
+ </ul>
41
+ </div>
42
+ </div>
43
+ <div id="about" class="information">
44
+ <div>
45
+ <h2>About</h2>
46
+ <h3>Incomplete beta version!</h3>
47
+ <p>
48
+ I'll add the full 3000k+ database of artists soon. I want to work out any major issues first. Please <a href="https://huggingface.co/spaces/mattthew/SDXL-artists-browser/discussions" target="_blank">give feedback on Huggingface</a>.
49
+ </p>
50
+ <h3>How to support this project</h3>
51
+ <ul>
52
+ <li>Please tell a friends or share on your socials</li>
53
+ <li>Suggest artists I should add or remove</li>
54
+ <li>Suggest features and report bugs</li>
55
+ <li><a href="https://huggingface.co/spaces/mattthew/SDXL-artists-browser/discussions" target="_blank">Leave all feedback on Huggingface</a></li>
56
+ <li>I don't need money. Thanks always feels nice!</li>
57
+ </ul>
58
+ <h3>Image parameters</h3>
59
+ <ul>
60
+ <li>
61
+ All: Steps: 20, Sampler: DPM++ 2M Karras, CFG scale: 10, Seed: 42, Size: 1024x1024, Model hash: 31e35c80fc, Model: sd_xl_base_1.0, Version: v1.5.1
62
+ </li>
63
+ <li>
64
+ 🎨 Prompt: by {Artist full name}, artwork image, Negative prompt: frame, border, text, signature
65
+ </li>
66
+ <li>
67
+ 🧑 Prompt: by {Artist full name}, image of a gently smiling, portrait of a person, head and torso, sitting in their room, Negative prompt: self-portrait, outside, frame, border, text, signature
68
+ </li>
69
+ <li>
70
+ 🏞️ Prompt: by {Artist full name}, image of a landscape, outdoor natural scenery, water, bridge, Negative prompt: people, person, frame, border, text, signature
71
+ </li>
72
+ </ul>
73
+ <h3>Disclaimers</h3>
74
+ <ul>
75
+ <li>This tools is just for fun. This information NOT be correct! The tags are from a mix of sources and manual input. Many tags are AI generated. I make corrections when I happen to spot them or when submitted.</li>
76
+ <li>Remember, SDXL is only a crude imitation of these artists. Check out these artists' actual artwork for more inspiration!</li>
77
+ <li>This database has more straight white male artists than in the actual population. That's because they've been favored by art-collectors, past and present. Please suggest artists I should add.</li>
78
+ <li>My code doesn't use cookies and sends nothing to any server. But it's hosted on Huggingface, and I can't control if they cookie you</li>
79
+ <li>Open source. Database is Creatives Commons licence</li>
80
+ <li>I don't get nor do I want compensation for this</li>
81
+ <li>I'm not affiliated with Stability AI</li>
82
+ <li>Use at your own risk 🧟</li>
83
+ </ul>
84
+ <h3>What's with the sedan?</h3>
85
+ <ul>
86
+ <li>
87
+ All images were generated with the same seed (42). For many artists, especially with the 🎨 prompt, that seed produces a car, which is not in the prompt. Other seeds will cause a different visual element across many artists.
88
+ </li>
89
+ </ul>
90
+ <h3>Missing images</h3>
91
+ <p>
92
+ If artists are listed in the database file, but their image files are missing, the files are listed below.
93
+ </p>
94
+ <ul id="missing_images_report"></ul>
95
+ </div>
96
+ </div>
97
+ <div id="export" class="information">
98
+ <div>
99
+ <h2>Export/Import favorited artists</h2>
100
+ <textarea placeholder="foo" autocomplete="You haven't favorited any artists yet."></textarea>
101
+ <div class="buttons">
102
+ <div id="export_to_clipboard">copy to clipboard</div>
103
+ <div id="export_import">import</div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ <div id="toggles">
108
+ <div id="options_info">
109
+ <span class="count">documents:</span>
110
+ <span class="link" id="infoI">⁉️&nbsp;</span>
111
+ <span class="link" id="infoA">📓&nbsp;</span>
112
+ <span class="link" id="infoX">📤&nbsp;</span>
113
+ </div>
114
+ <div id="options_prompts">
115
+ <span class="count">show me:</span>
116
+ <span class="link selected" id="promptA">🎨</span>
117
+ <span class="link" id="promptP">🧑</span>
118
+ <span class="link" id="promptL">🏞️</span>
119
+ </div>
120
+ <div id="options_artist_sort">
121
+ <span class="count">sort artists by:</span>
122
+ <span class="link selected" id="sortAR">🎰</span>
123
+ <span class="link" id="sortAA">🔠</span>
124
+ </div>
125
+ <div id="options_tag_sort">
126
+ <span class="count">sort tags by:</span>
127
+ <span class="link selected" id="sortTC">📶</span>
128
+ <span class="link" id="sortTA">🔠</span>
129
+ </div>
130
+ <div class="divider"></div>
131
+ <label class="top_control top_all">
132
+ <input type="checkbox" checked="checked" name="check-all" value="check-all" autocomplete="off"><span>all artists</span><span class="count"></span>
133
+ </label>
134
+ <div id="artistsShown" class="top_control">
135
+ <span class="count"></span>
136
+ </div>
137
+ <div class="divider"></div>
138
+ <label class="top_control">
139
+ <input type="checkbox" checked="checked" name="mode" value="mode" autocomplete="off"><span>permissive</span><span class="count"></span>
140
+ </label>
141
+ <label class="top_control">
142
+ <input type="checkbox" checked="checked" name="use_categories" value="use_categories" autocomplete="off"><span>use categories</span><span class="count"></span>
143
+ </label>
144
+ <label class="top_control">
145
+ <input type="checkbox" checked="checked" name="low_count" value="low_count" autocomplete="off"><span>hide low-use tags</span><span class="count"></span>
146
+ </label>
147
+ <label class="top_control">
148
+ <input type="checkbox" checked="checked" name="favorite" value="favorite" autocomplete="off"><span>favorited</span><span class="count"></span>
149
+ </label>
150
+ <div class="divider"></div>
151
+ <span id="edit_most_used" class="hidden">edit</span>
152
+ <!-- JS will insert checkboxes here -->
153
+ </div>
154
+ <div id="gutter"></div>
155
+ <div id="image-container">
156
+ <div id="filtersHidingAll">
157
+ these filters hide every image<br>
158
+ check-mark any tag or ‟permissive”<br>
159
+ 👀
160
+ </div>
161
+ <!-- JS will insert images here -->
162
+ <!--
163
+ <div class="image-item tag1 tag2">
164
+ <span>
165
+ <h3>
166
+ <span class="firstN">Name</span>
167
+ <span class="lastN">Name</span>
168
+ </h3>
169
+ <h4>
170
+ tag1, tag2
171
+ </h4>
172
+ </span>
173
+ <div>
174
+ <div class="imgTools">
175
+ <div class="art_prev"></div>
176
+ <div class="art_star"></div>
177
+ <div class="art_next"></div>
178
+ </div>
179
+ <div class="imgBox">
180
+ <img alt="First Last - art" src="images/SDXL_1_0/First_Last-artwork.jpg">
181
+ <img alt="First Last - art" src="images/SDXL_1_0/First_Last-potrait.jpg">
182
+ <img alt="First Last - art" src="images/SDXL_1_0/First_Last-landscape.jpg">
183
+ </div>
184
+ </div>
185
+ </div>
186
+ -->
187
+ </div>
188
  </div>
189
+ <footer class="special">
190
+ <div>
191
+ <span><strong>Beta v0.9 - Missing 2,500 artist! Click the 📓 at the top left -</strong></span>
192
+ <span>Enjoy this SDXL artist browser by</span>
193
+ <a href="https://huggingface.co/mattthew" target="_blank">Mattthew</a>
194
+ <div id="close_footer"><strong>&nbsp;&nbsp;x&nbsp;&nbsp;</strong></div>
195
+ </div>
196
+ </footer>
197
+ </div>
198
+ <div id="alert"></div>
199
  </body>
200
+ </html>
index.js ADDED
@@ -0,0 +1,1406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ //
3
+ //
4
+ //
5
+ // global variables
6
+ var timer;
7
+ var artTypes = ['🎨','🧑','🏞️'];
8
+ var imgTypeShown = 0;
9
+ var log = '';
10
+ var editMode = false;
11
+ var windowWidth = 0;
12
+
13
+ //
14
+ //
15
+ //
16
+ // functions
17
+ function startUp() {
18
+ updateFooter();
19
+ insertArtists();
20
+ insertCheckboxesFromArtistsData();
21
+ insertCheckboxesFromCategories();
22
+ loadCheckboxesState();
23
+ showHideCategories();
24
+ loadOptionsState();
25
+ loadFavoritesState();
26
+ hideAllArtists();
27
+ unhideBasedOnPermissiveSetting();
28
+ updateArtistsCountPerTag('start');
29
+ rotatePromptsImages();
30
+ sortArtists();
31
+ sortTags();
32
+ loadMostUsedTags();
33
+ updateArtistsCountPerCategory();
34
+ showHideLowCountTags();
35
+ }
36
+
37
+ function updateFooter() {
38
+ let proto = window.location.protocol;
39
+ if (proto.startsWith('http')) {
40
+ var footer = document.getElementsByTagName('footer')[0];
41
+ footer.classList.add('special');
42
+ var el1 = document.createElement('span');
43
+ el1.textContent = 'Why are most artists are missing?! ';
44
+ el1.id = 'why';
45
+ footer.querySelectorAll('div')[0].prepend(el1);
46
+ }
47
+ }
48
+
49
+ function insertArtists() {
50
+ // artistsData is defined in the artists_and_tags.js file
51
+ let missingFiles = '';
52
+ var container = document.getElementById('image-container');
53
+ let imagePromises = artistsData.map((artist) => {
54
+ var last = artist[0];
55
+ var first = artist[1];
56
+ var tags1 = artist[2].replaceAll('|', ' ').toLowerCase();
57
+ // class names can't start with a number, but some tags do
58
+ // in these cases prepending with 'qqqq-'
59
+ tags1 = tags1.replace(/(^|\s)(\d)/g, '$1qqqq-$2');
60
+ var tags2 = artist[2].replaceAll('|', ', ').toLowerCase();
61
+ var itemDiv = document.createElement('div');
62
+ itemDiv.className = 'image-item ' + tags1;
63
+ var itemHeader = document.createElement('span');
64
+ var h3 = document.createElement('h3');
65
+ itemHeader.appendChild(h3);
66
+ var firstN = document.createElement('span');
67
+ var lastN = document.createElement('span');
68
+ firstN.className = 'firstN';
69
+ lastN.className = 'lastN';
70
+ firstN.textContent = `${first}`;
71
+ lastN.textContent = `${last}`;
72
+ h3.appendChild(firstN);
73
+ h3.appendChild(lastN);
74
+ h3.title = 'copy to clipboard';
75
+ var h4 = document.createElement('h4');
76
+ h4.textContent = tags2;
77
+ h4.title = 'check/uncheck these tags';
78
+ itemHeader.appendChild(h4);
79
+ itemDiv.appendChild(itemHeader);
80
+ var box = document.createElement('div');
81
+ var imgTools = document.createElement('div');
82
+ imgTools.className = 'imgTools';
83
+ var artPrev = document.createElement('div');
84
+ artPrev.className = 'art_prev';
85
+ var artPrevSpan = document.createElement('span');
86
+ artPrevSpan.textContent = '🧑';
87
+ artPrev.appendChild(artPrevSpan);
88
+ imgTools.appendChild(artPrev);
89
+ var artStar = document.createElement('div');
90
+ artStar.className = 'art_star';
91
+ var artStarSpan = document.createElement('span');
92
+ artStarSpan.textContent = '⭐️';
93
+ artStar.appendChild(artStarSpan);
94
+ imgTools.appendChild(artStar);
95
+ var artNext = document.createElement('div');
96
+ artNext.className = 'art_next';
97
+ var artNextSpan = document.createElement('span');
98
+ artNextSpan.textContent = '🏞️';
99
+ artNext.appendChild(artNextSpan);
100
+ imgTools.appendChild(artNext);
101
+ box.appendChild(imgTools);
102
+ var imgBox = document.createElement('div');
103
+ imgBox.className = 'imgBox';
104
+ var imgArtwork = document.createElement('img');
105
+ var imgPortrait = document.createElement('img');
106
+ var imgLandscape = document.createElement('img');
107
+ imgArtwork.alt = `${first} ${last}` + ' - artwork';
108
+ imgPortrait.alt = `${first} ${last}` + ' - portrait';
109
+ imgLandscape.alt = `${first} ${last}` + ' - landscape';
110
+ imgArtwork.className = 'img_artwork';
111
+ imgPortrait.className = 'img_portrait hidden';
112
+ imgLandscape.className = 'img_landscape hidden';
113
+ let src = 'images/SDXL_1_0_thumbs/';
114
+ if(first == '') {
115
+ src += last.replaceAll(' ', '_');
116
+ } else {
117
+ src += first.replaceAll(' ', '_') + '_' + last.replaceAll(' ', '_');
118
+ }
119
+ imgBox.appendChild(imgArtwork);
120
+ imgBox.appendChild(imgPortrait);
121
+ imgBox.appendChild(imgLandscape);
122
+ box.appendChild(imgBox);
123
+ itemDiv.appendChild(box);
124
+ container.appendChild(itemDiv);
125
+ return Promise.allSettled([
126
+ new Promise((resolve, reject) => {
127
+ imgArtwork.onload = resolve;
128
+ imgArtwork.onerror = () => {
129
+ missingFiles += '<li>' + first + '_' + last + '-artwork.webp</li>';
130
+ reject();
131
+ };
132
+ imgArtwork.src = src + '-artwork.webp';
133
+ }),
134
+ new Promise((resolve, reject) => {
135
+ imgPortrait.onload = resolve;
136
+ imgPortrait.onerror = () => {
137
+ missingFiles += '<li>' + first + '_' + last + '-portrait.webp</li>';
138
+ reject();
139
+ };
140
+ imgPortrait.src = src + '-portrait.webp';
141
+ }),
142
+ new Promise((resolve, reject) => {
143
+ imgLandscape.onload = resolve;
144
+ imgLandscape.onerror = () => {
145
+ missingFiles += '<li>' + first + '_' + last + '-landscape.webp</li>';
146
+ reject();
147
+ };
148
+ imgLandscape.src = src + '-landscape.webp';
149
+ })
150
+ ]);
151
+ });
152
+ let report = document.getElementById('missing_images_report');
153
+ Promise.allSettled(imagePromises).then(() => {
154
+ if(missingFiles.indexOf('webp')>0) {
155
+ report.innerHTML = missingFiles;
156
+ } else {
157
+ report.innerHTML = '<li>No thumbnails files are missing! Enlarged images are loaded on hover. If any are missing, they\'ll be listed here at that time.</li>'
158
+ }
159
+ });
160
+ }
161
+
162
+ function insertCheckboxesFromArtistsData() {
163
+ var uniqueTags = new Set();
164
+ artistsData.forEach(function(artist) {
165
+ var tags = artist[2].split('|');
166
+ tags.forEach(function(tag) {
167
+ uniqueTags.add(tag.toLowerCase());
168
+ });
169
+ });
170
+ var uTags = Array.from(uniqueTags);
171
+ var toggles = document.getElementById('toggles');
172
+ for(i=0,il=uTags.length;i<il;i++) {
173
+ if(uTags[i].length > 0) {
174
+ // 👆 shouldn't need to sanitize database, but just in case
175
+ var label = document.createElement('label');
176
+ var el = document.createElement('i');
177
+ el.className = 'most_used_indicator';
178
+ el.textContent = '+';
179
+ var input = document.createElement('input');
180
+ input.type = 'checkbox';
181
+ input.name = uTags[i];
182
+ input.value = uTags[i];
183
+ input.checked = true;
184
+ var span1 = document.createElement('span');
185
+ span1.textContent = uTags[i];
186
+ var span2 = document.createElement('span');
187
+ span2.className = 'count';
188
+ label.appendChild(el);
189
+ label.appendChild(input);
190
+ label.appendChild(span1);
191
+ label.appendChild(span2);
192
+ toggles.appendChild(label);
193
+ }
194
+ }
195
+ var checkAll = document.querySelector('input[name="check-all"]');
196
+ var divs = document.querySelectorAll('.image-item');
197
+ checkAll.parentNode.querySelector('.count').textContent = ' - ' + divs.length.toLocaleString();
198
+ }
199
+
200
+ function insertCheckboxesFromCategories() {
201
+ var useCategories = document.querySelector('input[name="use_categories"]').checked;
202
+ for(i=0,il=tagCategories.length;i<il;i++) {
203
+ let name = tagCategories[i][0];
204
+ var label = document.createElement('label');
205
+ label.dataset.categoryName = name;
206
+ label.className = 'category';
207
+ var input = document.createElement('input');
208
+ input.type = 'checkbox';
209
+ input.name = name;
210
+ input.value = name;
211
+ input.checked = true;
212
+ var span1 = document.createElement('span');
213
+ span1.textContent = name;
214
+ var span2 = document.createElement('span');
215
+ span2.className = 'count';
216
+ label.appendChild(input);
217
+ label.appendChild(span1);
218
+ label.appendChild(span2);
219
+ toggles.appendChild(label);
220
+ }
221
+ }
222
+
223
+ function loadCheckboxesState() {
224
+ let state = JSON.parse(localStorage.getItem('tagsChecked')) || {};
225
+ let allChecked = true;
226
+ for (let name in state) {
227
+ if (document.querySelector('input[name="'+name+'"]')) {
228
+ document.querySelector('input[name="'+name+'"]').checked = state[name];
229
+ if(name != 'mode' && name != 'use_categories') {
230
+ if(!state[name]) {
231
+ allChecked = false;
232
+ }
233
+ }
234
+ }
235
+ }
236
+ if(!allChecked) {
237
+ document.querySelector('input[name="check-all"]').checked = false;
238
+ }
239
+ }
240
+
241
+ function storeCheckboxState(checkbox) {
242
+ let state = JSON.parse(localStorage.getItem('tagsChecked')) || {};
243
+ state[checkbox.name] = checkbox.checked;
244
+ localStorage.setItem('tagsChecked', JSON.stringify(state));
245
+ }
246
+
247
+ function storeCheckboxStateAll(isChecked) {
248
+ let state = {};
249
+ var checkboxes = document.querySelectorAll('input[type="checkbox"]');
250
+ checkboxes.forEach(function(checkbox) {
251
+ let isTop = checkbox.parentNode.classList.contains('top_control');
252
+ if(!isTop || checkbox.name == 'favorite') {
253
+ // is a tag checkbox, not a setting
254
+ if(isChecked) {
255
+ state[checkbox.name] = true;
256
+ } else {
257
+ state[checkbox.name] = false;
258
+ }
259
+ }
260
+ });
261
+ localStorage.setItem('tagsChecked', JSON.stringify(state));
262
+ }
263
+
264
+ function loadOptionsState() {
265
+ let state = JSON.parse(localStorage.getItem('tagsChecked')) || {};
266
+ if(state['prompt']) {
267
+ document.getElementById('options_prompts').querySelectorAll('.selected')[0].classList.remove('selected');
268
+ document.getElementById(state['prompt']).classList.add('selected');
269
+ if(state['prompt'] == 'promptA') {
270
+ imgTypeShown = 0;
271
+ } else if(state['prompt'] == 'promptP') {
272
+ imgTypeShown = 1;
273
+ } else if(state['prompt'] == 'promptL') {
274
+ imgTypeShown = 2;
275
+ }
276
+ } else {
277
+ // promptA is already highlighted by HTML
278
+ imgTypeShown = 0;
279
+ }
280
+ if(state['artistSort']) {
281
+ document.getElementById('options_artist_sort').querySelectorAll('.selected')[0].classList.remove('selected');
282
+ document.getElementById(state['artistSort']).classList.add('selected');
283
+ } else {
284
+ // sortAR is already highlighted by HTML
285
+ }
286
+ if(state['tagSort']) {
287
+ document.getElementById('options_tag_sort').querySelectorAll('.selected')[0].classList.remove('selected');
288
+ document.getElementById(state['tagSort']).classList.add('selected');
289
+ } else {
290
+ // sortTC is already highlighted by HTML
291
+ }
292
+ }
293
+
294
+ function highlightSelectedOption(selected) {
295
+ if(selected == 'prev' || selected == 'next') {
296
+ if(selected == 'prev') {
297
+ imgTypeShown--;
298
+ if(imgTypeShown < 0) { imgTypeShown = 2; }
299
+ } else if(selected == 'next') {
300
+ imgTypeShown++;
301
+ if(imgTypeShown > 2) { imgTypeShown = 0; }
302
+ }
303
+ var links = document.getElementById('options_prompts').querySelectorAll('.link');
304
+ links.forEach(function(link) {
305
+ link.classList.remove('selected');
306
+ });
307
+ if(imgTypeShown == 0) {
308
+ document.getElementById('promptA').classList.add('selected');
309
+ doAlert('Showing artwork');
310
+ } else if(imgTypeShown == 1) {
311
+ document.getElementById('promptP').classList.add('selected');
312
+ doAlert('Showing portraits');
313
+ } else if(imgTypeShown == 2) {
314
+ document.getElementById('promptL').classList.add('selected');
315
+ doAlert('Showing landscapes');
316
+ }
317
+ } else {
318
+ if(selected == 'promptA') {
319
+ imgTypeShown = 0;
320
+ doAlert('Showing artwork');
321
+ } else if(selected == 'promptP') {
322
+ imgTypeShown = 1;
323
+ doAlert('Showing portraits');
324
+ } else if(selected == 'promptL') {
325
+ imgTypeShown = 2;
326
+ doAlert('Showing landscapes');
327
+ }
328
+ var links = document.getElementById(selected).parentNode.querySelectorAll('.link');
329
+ links.forEach(function(link) {
330
+ link.classList.remove('selected');
331
+ });
332
+ document.getElementById(selected).classList.add('selected');
333
+ }
334
+ }
335
+
336
+ function storeOptionsState() {
337
+ let state = JSON.parse(localStorage.getItem('tagsChecked')) || {};
338
+ if(document.getElementById('promptA').classList.contains('selected')) {
339
+ state['prompt'] = 'promptA';
340
+ } else if(document.getElementById('promptP').classList.contains('selected')) {
341
+ state['prompt'] = 'promptP';
342
+ } else {
343
+ state['prompt'] = 'promptL';
344
+ }
345
+ if(document.getElementById('sortAR').classList.contains('selected')) {
346
+ state['artistSort'] = 'sortAR';
347
+ } else {
348
+ state['artistSort'] = 'sortAA';
349
+ }
350
+ if(document.getElementById('sortTC').classList.contains('selected')) {
351
+ state['tagSort'] = 'sortTC';
352
+ } else {
353
+ state['tagSort'] = 'sortTA';
354
+ }
355
+ localStorage.setItem('tagsChecked', JSON.stringify(state));
356
+ }
357
+
358
+ function rotatePromptsImages() {
359
+ // hide all images
360
+ let images = document.querySelectorAll('.imgBox img');
361
+ images.forEach(function(image) {
362
+ image.classList.add('hidden');
363
+ });
364
+ // unhide images matching highlighted option (imgTypeShown)
365
+ if(imgTypeShown == 0) {
366
+ images = document.querySelectorAll('.img_artwork');
367
+ } else if(imgTypeShown == 1) {
368
+ images = document.querySelectorAll('.img_portrait');
369
+ } else if(imgTypeShown == 2) {
370
+ images = document.querySelectorAll('.img_landscape');
371
+ }
372
+ images.forEach(function(image) {
373
+ image.classList.remove('hidden');
374
+ });
375
+ // switch prev and next button icons
376
+ let artIndex = 0;
377
+ artIndex = imgTypeShown-1;
378
+ if(artIndex < 0) { artIndex = 2; }
379
+ let prevButtons = document.querySelectorAll('.art_prev span');
380
+ prevButtons.forEach(function(span) {
381
+ span.textContent = artTypes[artIndex];
382
+ });
383
+ artIndex = imgTypeShown+1;
384
+ if(artIndex > 2) { artIndex = 0; }
385
+ let nextButtons = document.querySelectorAll('.art_next span');
386
+ nextButtons.forEach(function(span) {
387
+ span.textContent = artTypes[artIndex];
388
+ });
389
+ }
390
+
391
+ function updateArtistsCountPerTag(whoCalled) {
392
+ var permissiveCheckbox = document.querySelector('input[name="mode"]');
393
+ var checkboxes = document.querySelectorAll('input[type="checkbox"]');
394
+ var divs = document.querySelectorAll('.image-item');
395
+ var hiddenDivs = document.querySelectorAll('.image-item.hidden');
396
+ if(permissiveCheckbox.checked || whoCalled == 'start') {
397
+ // on page load, we need to add all the counts first
398
+ checkboxes.forEach(function(checkbox) {
399
+ let isTop = checkbox.parentNode.classList.contains('top_control');
400
+ if(!isTop) {
401
+ var theClass = checkbox.name.replace(/(^|\s)(\d)/g, '$1qqqq-$2');
402
+ var matchingDivs = document.querySelectorAll('.image-item.' + theClass);
403
+ var count = matchingDivs.length;
404
+ checkbox.parentNode.classList.remove('no_matches');
405
+ checkbox.parentNode.querySelector('input').disabled = false;
406
+ checkbox.parentNode.querySelector('.count').textContent = ' - ' + count.toLocaleString();
407
+ }
408
+ });
409
+ updateArtistsCountPerCategory();
410
+ }
411
+ if(!permissiveCheckbox.checked) {
412
+ checkboxes.forEach(function(checkbox) {
413
+ let isTop = checkbox.parentNode.classList.contains('top_control');
414
+ if(!isTop) {
415
+ var count = 0;
416
+ // class names can't start with a number, but some tags do
417
+ // in these cases prepending with 'qqqq-'
418
+ var theClass = checkbox.name.replace(/(^|\s)(\d)/g, '$1qqqq-$2');
419
+ if(!permissiveCheckbox.checked) {
420
+ // for strict mode, for each checkbox, only count artists with a classes matching all checked checkboxes
421
+ var matchingDivs = document.querySelectorAll('.image-item.' + theClass + ':not(.hidden)');
422
+ count = matchingDivs.length;
423
+ if(count == 0) {
424
+ checkbox.parentNode.classList.add('no_matches');
425
+ checkbox.parentNode.querySelector('input').disabled = true;
426
+ } else {
427
+ checkbox.parentNode.classList.remove('no_matches');
428
+ checkbox.parentNode.querySelector('input').disabled = false;
429
+ }
430
+ }
431
+ checkbox.parentNode.querySelector('.count').textContent = ' - ' + count.toLocaleString();
432
+ }
433
+ });
434
+ }
435
+ updateCountOfArtistsShown(divs, hiddenDivs);
436
+ }
437
+
438
+ function updateArtistsCountPerCategory() {
439
+ var imageItems = document.querySelectorAll('.image-item');
440
+ let counts = [];
441
+ for(i=0,il=tagCategories.length; i<il; i++) {
442
+ counts[i] = 0;
443
+ }
444
+ imageItems.forEach(function(imageItem) {
445
+ var classes = Array.from(imageItem.classList).map(className => {
446
+ // class names can't start with a number,
447
+ // so some classes were prepending with 'qqqq-'
448
+ // which must be ignored
449
+ return className.replace(/^qqqq-/, '');
450
+ });
451
+ for(i=0,il=tagCategories.length; i<il; i++) {
452
+ if(tagCategories[i].map(c => c.toLowerCase()).some(c => classes.includes(c))) {
453
+ counts[i]++;
454
+ }
455
+ }
456
+ });
457
+ for(i=0,il=tagCategories.length; i<il; i++) {
458
+ let label = document.querySelector('[data-category-name="' + tagCategories[i][0] + '"]');
459
+ label.querySelector('.count').textContent = ' - ' + counts[i].toLocaleString();
460
+ }
461
+ }
462
+
463
+ function updateCountOfArtistsShown(divs, hiddenDivs) {
464
+ if(!divs) {
465
+ // when this is called by change of a checkbox, divs is not passed
466
+ var divs = document.querySelectorAll('.image-item');
467
+ var hiddenDivs = document.querySelectorAll('.image-item.hidden');
468
+ }
469
+ var visible = divs.length - hiddenDivs.length;
470
+ var percent = Math.round((visible / divs.length) * 100) + '%';
471
+ if(percent == '0%') {
472
+ percent = '<1%';
473
+ }
474
+ var el = document.getElementById('artistsShown').querySelector('.count');
475
+ el.textContent = 'shown - ' + visible.toLocaleString() + ' / ' + percent;
476
+ }
477
+
478
+ function checkAllInCategory(theCheckbox) {
479
+ let thisLabel = theCheckbox.parentNode;
480
+ if (thisLabel.classList.contains('category')) {
481
+ let container = document.getElementById('toggles');
482
+ let labels = container.getElementsByTagName('label');
483
+ let isChecking = false;
484
+ for (let label of labels) {
485
+ // If we reach 'thisLabel', start checking.
486
+ if(label === thisLabel) {
487
+ isChecking = true;
488
+ continue; // Skip 'thisLabel' itself.
489
+ }
490
+ // If 'isChecking' is true and we found another 'category', stop checking.
491
+ if(isChecking && label.classList.contains('category')) {
492
+ break;
493
+ }
494
+ // If 'isChecking' is true, check or uncheck the checkbox inside the current label.
495
+ if(isChecking) {
496
+ if(!label.classList.contains('hidden')) {
497
+ // hidden labels must remain unchecked
498
+ let checkbox = label.querySelector('input[type="checkbox"]');
499
+ if(checkbox) {
500
+ checkbox.checked = theCheckbox.checked;
501
+ }
502
+ }
503
+ }
504
+ }
505
+ }
506
+ }
507
+
508
+ function hideAllArtists() {
509
+ var imageItems = document.querySelectorAll('.image-item');
510
+ imageItems.forEach(function(imageItem) {
511
+ imageItem.classList.add('hidden');
512
+ });
513
+ }
514
+
515
+ function unhideBasedOnPermissiveSetting() {
516
+ var permissiveCheckbox = document.querySelector('input[name="mode"]');
517
+ if(permissiveCheckbox.checked) {
518
+ permissiveCheckbox.parentNode.classList.remove('warning');
519
+ unhideArtistsPermissive();
520
+ } else {
521
+ permissiveCheckbox.parentNode.classList.add('warning');
522
+ unhideArtistsStrict();
523
+ }
524
+ var unHidden = document.querySelectorAll('.image-item').length - document.querySelectorAll('.image-item.hidden').length;
525
+ if(unHidden == 0) {
526
+ document.getElementById('filtersHidingAll').classList.add('shown');
527
+ } else {
528
+ document.getElementById('filtersHidingAll').classList.remove('shown');
529
+ }
530
+ }
531
+
532
+ function unhideArtistsPermissive() {
533
+ // permissive mode unhides images that match ANY checked tag
534
+ // the set of checkboxes is derived from the unique tags within the imageItem (Artists) classes
535
+ var imageItems = document.querySelectorAll('.image-item');
536
+ var checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]'))
537
+ .filter(cb => !cb.parentNode.classList.contains("top_control"));
538
+ checkboxes.push(document.querySelector('input[name="favorite"]'));
539
+ var checked = checkboxes.filter(cb => cb.checked).map(cb => cb.name);
540
+ imageItems.forEach(function(imageItem) {
541
+ var classes = Array.from(imageItem.classList).map(className => {
542
+ // class names can't start with a number,
543
+ // so some classes were prepending with 'qqqq-'
544
+ // which must be ignored
545
+ return className.replace(/^qqqq-/, '');
546
+ });
547
+ if(checked.some(c => classes.includes(c))) {
548
+ imageItem.classList.remove('hidden');
549
+ }
550
+ });
551
+ }
552
+
553
+ function unhideArtistsStrict() {
554
+ // strict mode unhides images that match ALL checked tags
555
+ // the set of checkboxes is derived from the unique tags within the imageItem (Artists) classes
556
+ var imageItems = document.querySelectorAll('.image-item');
557
+ var checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]'))
558
+ .filter(cb => !cb.parentNode.classList.contains("top_control"));
559
+ checkboxes.push(document.querySelector('input[name="favorite"]'));
560
+ var checked = checkboxes.filter(cb => cb.checked).map(cb => cb.name);
561
+ if(checked.length > 0) {
562
+ imageItems.forEach(function(imageItem, index) {
563
+ var classes = Array.from(imageItem.classList).map(className => {
564
+ // class names can't start with a number,
565
+ // so some classes were prepending with 'qqqq-'
566
+ // which must be ignored
567
+ return className.replace(/^qqqq-/, '');
568
+ });
569
+ if(checked.every(c => classes.includes(c))) {
570
+ imageItem.classList.remove('hidden');
571
+ }
572
+ });
573
+ } else {
574
+ // while not strictly logical, it's needed because
575
+ // nothing would be checkable if strict is entered while everything is unchecked
576
+ imageItems.forEach(function(imageItem) {
577
+ imageItem.classList.remove('hidden');
578
+ });
579
+ }
580
+ }
581
+
582
+ function unhideAristsExact() {
583
+ // exact mode isn't currently used because almost no two artists have the same set of tags
584
+ // exact mode unhides images that match ALL checked tags and NO unchecked tags
585
+ // the set of checkboxes is derived from the unique tags within the imageItem (Artists) classes
586
+ var imageItems = document.querySelectorAll('.image-item');
587
+ var checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]'))
588
+ .filter(cb => !cb.parentNode.classList.contains("top_control"));
589
+ checkboxes.push(document.querySelector('input[name="favorite"]'));
590
+ var checked = checkboxes.filter(cb => cb.checked).map(cb => cb.name);
591
+ var unchecked = checkboxes.filter(cb => !cb.checked).map(cb => cb.name);
592
+ if(checked.length > 0) {
593
+ imageItems.forEach(function(imageItem, index) {
594
+ var classes = Array.from(imageItem.classList);
595
+ if(checked.every(c => classes.includes(c))) {
596
+ if(unchecked.every(c => !classes.includes(c))) {
597
+ imageItem.classList.remove('hidden');
598
+ }
599
+ }
600
+ });
601
+ }
602
+ }
603
+
604
+ function checkOrUncheckAll(isChecked) {
605
+ var divs = document.querySelectorAll('.image-item');
606
+ var checkboxes = document.querySelectorAll('input[type="checkbox"]');
607
+ if(isChecked) {
608
+ checkboxes.forEach(function(checkbox) {
609
+ let label = checkbox.parentNode;
610
+ let isTop = label.classList.contains('top_control');
611
+ let isHidden = label.classList.contains('hidden');
612
+ if(!isTop || checkbox.name == 'favorite') {
613
+ if(!isHidden) {
614
+ // hidden label must not be checked
615
+ checkbox.checked = true;
616
+ }
617
+ };
618
+ });
619
+ } else {
620
+ checkboxes.forEach(function(checkbox) {
621
+ let label = checkbox.parentNode;
622
+ let isTop = label.classList.contains('top_control');
623
+ if(!isTop || checkbox.name == 'favorite') {
624
+ checkbox.checked = false;
625
+ }
626
+ });
627
+ }
628
+ }
629
+
630
+ function showInstructions() {
631
+ document.getElementById('instructions').classList.add('shown');
632
+ hideToggles();
633
+ }
634
+
635
+ function showAbout() {
636
+ document.getElementById('about').classList.add('shown');
637
+ hideToggles();
638
+ }
639
+
640
+ function showExport() {
641
+ document.getElementById('export').classList.add('shown');
642
+ hideToggles();
643
+ var textarea = document.getElementById('export').getElementsByTagName('textarea')[0];
644
+ var favorites = localStorage.getItem('favoritedArtists');
645
+ var value = '';
646
+ if(favorites) {
647
+ value += 'You have favorited these artists:\r\n';
648
+ for (let key in JSON.parse(favorites)) {
649
+ if (JSON.parse(favorites)[key] === true) {
650
+ let names = key.split("|");
651
+ if(!names[0]) { names[0] = '(no first name)'; }
652
+ value += '•' + names[0] + ',' + names[1] + '\r\n';
653
+ }
654
+ }
655
+ value += '\r\n\r\nTo import these favorites later, click "copy to clipboard" and save to any file. Then paste the text from that file into this text box, and click "import". The imported text must contain the JSON string below (the curly brackets and what\'s between them). It must not contain any other more than one set of curly brackets.\r\n\r\n' + favorites;
656
+ textarea.value = value;
657
+ } else {
658
+ value += 'You haven\'t favorited any artists yet.\r\n\r\n';
659
+ value += 'To import favorites that you exported earlier, paste the text into this text box, and click "import".';
660
+ }
661
+ }
662
+
663
+ function copyExportToClipboard() {
664
+ var favorites = document.getElementById('export').getElementsByTagName('textarea')[0].value;
665
+ navigator.clipboard.writeText(favorites);
666
+ doAlert('Favorites copied to clipboard!');
667
+ }
668
+
669
+ function importFavorites() {
670
+ let el = document.getElementById('export').getElementsByTagName('textarea')[0];
671
+ let favorites = el.value;
672
+ let startCount = (favorites.match(/{/g) || []).length;
673
+ let endCount = (favorites.match(/}/g) || []).length;
674
+ if (startCount > 1 || endCount > 1) {
675
+ el.value = 'That text can\'t be imported because it contains multiple curly brackets {}.'
676
+ return null;
677
+ }
678
+ let start = favorites.indexOf('{');
679
+ let end = favorites.lastIndexOf('}');
680
+ if (start === -1 || end === -1) {
681
+ el.value = 'That text can\'t be imported because it contains zero curly brackets {}.'
682
+ return null;
683
+ }
684
+ let jsonString = favorites.substring(start, end + 1);
685
+ try {
686
+ let jsonObject = JSON.parse(jsonString);
687
+ // Check structure of each key-value pair in jsonObject
688
+ for (let key in jsonObject) {
689
+ let value = jsonObject[key];
690
+ if (!key.includes('|') || typeof value !== 'boolean') {
691
+ el.value = 'That text can\'t be imported because the JSON string it contains doesn\'t contain a valid list of artists.'
692
+ return null;
693
+ }
694
+ }
695
+ if(confirm('This will overwrite any saved favorites. Are you sure?')) {
696
+ localStorage.setItem('favoritedArtists', jsonString);
697
+ alert('Favorites were imported!');
698
+ loadFavoritesState();
699
+ } else {
700
+ alert('Okay, you have cancelled the import.');
701
+ return null;
702
+ }
703
+ } catch(e) {
704
+ el.value = 'That text can\'t be imported because it doesn\'t contain a valid JSON sting.'
705
+ return null;
706
+ }
707
+ }
708
+
709
+ function hideInformation() {
710
+ var information = document.querySelectorAll('.information');
711
+ information.forEach(function(element) {
712
+ element.classList.remove('shown');
713
+ });
714
+ showToggles();
715
+ }
716
+
717
+ function sortTags() {
718
+ if(document.getElementById('sortTC').classList.contains('selected')) {
719
+ sortTagsByCount();
720
+ } else {
721
+ sortTagsByAlpha();
722
+ }
723
+ }
724
+
725
+ function sortTagsByAlpha() {
726
+ var useCategories = document.querySelector('input[name="use_categories"]').checked;
727
+ let container = document.getElementById('toggles');
728
+ let labels = Array.from(container.getElementsByTagName('label'));
729
+ if (!useCategories) {
730
+ // <labels> with class="category" are hidden, sort all other labels together by alpha
731
+ labels.sort(function(a, b) {
732
+ var aValue = a.querySelector('input[type="checkbox"]').name;
733
+ var bValue = b.querySelector('input[type="checkbox"]').name;
734
+ return aValue.localeCompare(bValue);
735
+ });
736
+ labels.forEach(function(label) {
737
+ let isTop = label.classList.contains('top_control');
738
+ if(!isTop) {
739
+ // appendChild will move the element to the end of the container
740
+ container.appendChild(label);
741
+ }
742
+ });
743
+ } else {
744
+ let labelMap = labels.reduce((acc, label) => {
745
+ // map: keys are checkbox names, values are corresponding parent label element
746
+ let checkboxName = label.querySelector('input[type="checkbox"]').name;
747
+ acc[checkboxName.toLowerCase()] = label;
748
+ return acc;
749
+ }, {});
750
+ // sort tags that exist in tagCategories under that category
751
+ tagCategories.forEach(arrayOfTags => {
752
+ // first append the label that matches the category name
753
+ let categoryName = arrayOfTags[0];
754
+ let categoryLabel = labelMap[categoryName.toLowerCase()];
755
+ if (categoryLabel) {
756
+ container.appendChild(categoryLabel);
757
+ }
758
+ // the append the sorted labels that match the tag
759
+ let arrayOfTagsLower = arrayOfTags.slice(1).map(tag => tag.toLowerCase());
760
+ arrayOfTagsLower.sort();
761
+ arrayOfTagsLower.forEach(tag => {
762
+ let label = labelMap[tag];
763
+ if (label) {
764
+ let isTop = label.classList.contains('top_control');
765
+ if(!isTop) {
766
+ label.dataset.isInCategory = categoryLabel.dataset.categoryName;
767
+ // appendChild will move the element to the end of the container
768
+ container.appendChild(label);
769
+ }
770
+ // remove this label from the map
771
+ delete labelMap[tag];
772
+ }
773
+ });
774
+ if(categoryName == 'important') {
775
+ container.appendChild(document.getElementById('edit_most_used'));
776
+ }
777
+ });
778
+ // this leaves all the tags that didn't exist in tagCategories sorted at the top
779
+ let leftoverLabelsKeys = Object.keys(labelMap);
780
+ leftoverLabelsKeys.sort();
781
+ leftoverLabelsKeys.forEach(key => {
782
+ let label = labelMap[key];
783
+ if (label && !label.classList.contains('top_control') && !label.classList.contains('category')) {
784
+ label.dataset.isInCategory = 'other';
785
+ container.appendChild(label);
786
+ }
787
+ });
788
+ }
789
+ }
790
+
791
+ function sortTagsByCount() {
792
+ var useCategories = document.querySelector('input[name="use_categories"]').checked;
793
+ let container = document.getElementById('toggles');
794
+ let labels = Array.from(container.getElementsByTagName('label'));
795
+ if (!useCategories) {
796
+ labels.sort(function(a, b) {
797
+ var numA = parseInt(a.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2),10);
798
+ var numB = parseInt(b.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2),10);
799
+ return numB - numA;
800
+ });
801
+ labels.forEach(function(label) {
802
+ let isTop = label.classList.contains('top_control');
803
+ if(!isTop) {
804
+ // appendChild will move the element to the end of the container
805
+ container.appendChild(label);
806
+ }
807
+ });
808
+ } else {
809
+ let labelMap = labels.reduce((acc, label) => {
810
+ // map: keys are checkbox names, values are corresponding parent label element
811
+ let checkboxName = label.querySelector('input[type="checkbox"]').name;
812
+ acc[checkboxName.toLowerCase()] = label;
813
+ return acc;
814
+ }, {});
815
+ tagCategories.forEach(arrayOfTags => {
816
+ let categoryName = arrayOfTags[0];
817
+ let categoryLabel = labelMap[categoryName.toLowerCase()];
818
+ if (categoryLabel) {
819
+ container.appendChild(categoryLabel);
820
+ }
821
+ // get the list of tags from the category array
822
+ let arrayOfTagsLower = arrayOfTags.slice(1).map(tag => tag.toLowerCase());
823
+ // Sort by the number in each label
824
+ arrayOfTagsLowerExisting = [];
825
+ arrayOfTagsLower.forEach(function(tag) {
826
+ if(labelMap[tag]) {
827
+ arrayOfTagsLowerExisting.push(tag);
828
+ }
829
+ });
830
+ arrayOfTagsLowerExisting.sort((a, b) => {
831
+ let labelA = labelMap[a];
832
+ let labelB = labelMap[b];
833
+ if(labelA && labelB){
834
+ let numA = parseInt(labelA.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10);
835
+ let numB = parseInt(labelB.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10);
836
+ return numB - numA;
837
+ } else {
838
+ return 0;
839
+ }
840
+ });
841
+ arrayOfTagsLowerExisting.forEach(tag => {
842
+ let label = labelMap[tag];
843
+ if (label) {
844
+ let isTop = label.classList.contains('top_control');
845
+ if (!isTop) {
846
+ // appendChild will move the element to the end of the container
847
+ label.dataset.isInCategory = categoryLabel.dataset.categoryName;
848
+ container.appendChild(label);
849
+ }
850
+ // remove this label from the map
851
+ delete labelMap[tag];
852
+ }
853
+ });
854
+ if(categoryName == 'important') {
855
+ container.appendChild(document.getElementById('edit_most_used'));
856
+ }
857
+ });
858
+ let leftoverLabelsKeys = Object.keys(labelMap);
859
+ // Sort the leftover labels keys by the number in each label
860
+ leftoverLabelsKeys.sort((a, b) => {
861
+ let labelA = labelMap[a];
862
+ let labelB = labelMap[b];
863
+ if(labelA && labelB){
864
+ let numA = parseInt(labelA.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10);
865
+ let numB = parseInt(labelB.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2), 10);
866
+ return numB - numA;
867
+ } else {
868
+ return 0;
869
+ }
870
+ });
871
+ leftoverLabelsKeys.forEach(key => {
872
+ let label = labelMap[key];
873
+ if (label && !label.classList.contains('top_control') && !label.classList.contains('category')) {
874
+ label.dataset.isInCategory = 'other';
875
+ container.appendChild(label);
876
+ }
877
+ });
878
+ }
879
+ }
880
+
881
+ function loadMostUsedTags() {
882
+ let state = JSON.parse(localStorage.getItem('mustUsedTags')) || {};
883
+ let mostUsedCategory = document.querySelector('[data-category-name="important"]');
884
+ for(let tag in state) {
885
+ if (state[tag]) {
886
+ let label = document.querySelector('input[name="'+ tag +'"]').parentNode;
887
+ label.classList.add('is_most_used');
888
+ label.querySelectorAll('.most_used_indicator')[0].textContent = '-';
889
+ mostUsedCategory.after(label);
890
+ updateTagArrayToMatchMostUsed(true,label,tag);
891
+ }
892
+ };
893
+ }
894
+
895
+ function updateTagArrayToMatchMostUsed(isAdding,label,tag) {
896
+ // need to updated tagCategories because it's used to show sums of the categories
897
+ // the first category in tagCategories stores the important tags unless the database is messed up
898
+ if(isAdding) {
899
+ tagCategories[0].push(tag);
900
+ // remove tag from its original category
901
+ for(i=0,il<tagCategories.length; i<il; i++) {
902
+ if(tagCategories[i][0] == label.dataset.isInCategory) {
903
+ tagCategories[i] = tagCategories[i].filter(function(ele){
904
+ return ele != tag;
905
+ });
906
+ break;
907
+ }
908
+ }
909
+ } else {
910
+ tagCategories[0] = tagCategories[0].filter(function(ele){
911
+ return ele != tag;
912
+ });
913
+ // add tag back to it's original category
914
+ for(i=0,il<tagCategories.length; i<il; i++) {
915
+ if(tagCategories[i][0] == label.dataset.isInCategory) {
916
+ tagCategories[i].push(tag);
917
+ break;
918
+ }
919
+ }
920
+ }
921
+ }
922
+
923
+ function storeMostUsedState(label) {
924
+ var name = label.querySelector('input').name;
925
+ let state = JSON.parse(localStorage.getItem('mustUsedTags')) || {};
926
+ state[name] = label.classList.contains('is_most_used');
927
+ localStorage.setItem('mustUsedTags', JSON.stringify(state));
928
+ }
929
+
930
+ function enterExitEditMostUsedMode(doExit) {
931
+ let inputs = Array.from(document.querySelectorAll('input'));
932
+ if(editMode || doExit) {
933
+ // exit edit mode
934
+ editMode = false;
935
+ document.getElementById('edit_most_used').textContent = 'edit';
936
+ document.getElementById('layout').classList.remove('edit_mode');
937
+ inputs.forEach(function(input) {
938
+ input.disabled = false;
939
+ });
940
+ let labels = Array.from(document.querySelectorAll('.was_moved'));
941
+ labels.forEach(function(label) {
942
+ // clean up classes added to track moved tags during edit mode
943
+ label.classList.remove('was_moved');
944
+ })
945
+ updateArtistsCountPerCategory();
946
+ } else {
947
+ // enter edit mode
948
+ editMode = true;
949
+ document.getElementById('edit_most_used').textContent = 'exit editing';
950
+ document.getElementById('layout').classList.add('edit_mode');
951
+ inputs.forEach(function(input) {
952
+ input.disabled = true;
953
+ });
954
+ }
955
+ }
956
+
957
+ function addRemoveIsMostUsed(label) {
958
+ let mostUsedCategory = document.querySelector('[data-category-name="important"]');
959
+ if(label.classList.contains('is_most_used')) {
960
+ // remove it
961
+ label.classList.remove('is_most_used');
962
+ label.querySelectorAll('.most_used_indicator')[0].textContent = '+';
963
+ let originalCategory = document.querySelector('[data-category-name="' + label.dataset.isInCategory + '"]');
964
+ originalCategory.after(label);
965
+ updateTagArrayToMatchMostUsed(false,label,label.querySelector('input').name);
966
+ } else {
967
+ // add it
968
+ label.classList.add('is_most_used');
969
+ label.querySelectorAll('.most_used_indicator')[0].textContent = '-';
970
+ mostUsedCategory.after(label);
971
+ updateTagArrayToMatchMostUsed(true,label,label.querySelector('input').name);
972
+ }
973
+ label.classList.add('was_moved');
974
+ }
975
+
976
+ function sortArtists() {
977
+ if(document.getElementById('sortAR').classList.contains('selected')) {
978
+ sortArtistsByRandom();
979
+ } else {
980
+ sortArtistsByAlpha();
981
+ }
982
+ }
983
+
984
+ function sortArtistsByAlpha() {
985
+ var imageItems = Array.from(document.querySelectorAll('.image-item'));
986
+ imageItems.sort(function(a, b) {
987
+ var aValue = a.querySelector('.lastN').textContent;
988
+ var bValue = b.querySelector('.lastN').textContent;
989
+ return aValue.localeCompare(bValue);
990
+ });
991
+ imageItems.forEach(function(item) {
992
+ // appendChild will move the element to the end of the container
993
+ document.getElementById('image-container').appendChild(item);
994
+ });
995
+ }
996
+
997
+ function sortArtistsByRandom() {
998
+ var imageItems = Array.from(document.querySelectorAll('.image-item'));
999
+ imageItems.forEach(function(item) {
1000
+ item.dataset.randomRank = Math.random();
1001
+ });
1002
+ imageItems.sort(function(a, b) {
1003
+ var aValue = a.dataset.randomRank;
1004
+ var bValue = b.dataset.randomRank;
1005
+ return bValue - aValue;
1006
+ });
1007
+ imageItems.forEach(function(item) {
1008
+ // appendChild will move the element to the end of the container
1009
+ document.getElementById('image-container').appendChild(item);
1010
+ });
1011
+ }
1012
+
1013
+ function hideToggles() {
1014
+ document.getElementById('toggles').classList.add('hide');
1015
+ }
1016
+
1017
+ function showToggles() {
1018
+ document.getElementById('toggles').classList.remove('hide');
1019
+ }
1020
+
1021
+ function addOrRemoveFavorite(artist) {
1022
+ if(artist.classList.contains('favorite')) {
1023
+ artist.classList.remove('favorite');
1024
+ } else {
1025
+ artist.classList.add('favorite');
1026
+ }
1027
+ }
1028
+
1029
+ function loadFavoritesState() {
1030
+ let state = JSON.parse(localStorage.getItem('favoritedArtists')) || {};
1031
+ let artists = document.getElementsByClassName('image-item');
1032
+ for(let artist of artists) {
1033
+ let artistName = artist.getElementsByClassName('firstN')[0].textContent + '|' + artist.getElementsByClassName('lastN')[0].textContent;
1034
+ if(state[artistName]) {
1035
+ artist.classList.add('favorite');
1036
+ } else {
1037
+ artist.classList.remove('favorite');
1038
+ }
1039
+ }
1040
+ updateFavoritesCount();
1041
+ }
1042
+
1043
+ function storeFavoriteState(artist) {
1044
+ var artistName = artist.getElementsByClassName('firstN')[0].textContent + '|' + artist.getElementsByClassName('lastN')[0].textContent;
1045
+ var isFavorited = artist.classList.contains('favorite');
1046
+ let state = JSON.parse(localStorage.getItem('favoritedArtists')) || {};
1047
+ state[artistName] = isFavorited;
1048
+ localStorage.setItem('favoritedArtists', JSON.stringify(state));
1049
+ }
1050
+
1051
+ function updateFavoritesCount() {
1052
+ var favoritedArtists = document.getElementsByClassName('favorite');
1053
+ var favoriteCount = favoritedArtists.length;
1054
+ var favoriteCounter = document.querySelectorAll('input[name="favorite"]')[0].parentNode.querySelector('.count');
1055
+ favoriteCounter.textContent = ' - ' + favoriteCount;
1056
+ }
1057
+
1058
+ function doAlert(str) {
1059
+ var alert = document.getElementById('alert');
1060
+ alert.textContent = str;
1061
+ alert.classList.remove('show');
1062
+ window.clearTimeout(timer);
1063
+ timer = setTimeout(showAlert, 100);
1064
+ }
1065
+
1066
+ function showAlert() {
1067
+ var alert = document.getElementById('alert');
1068
+ alert.classList.add('show');
1069
+ timer = setTimeout(hideAlert, 2000);
1070
+ }
1071
+
1072
+ function hideAlert() {
1073
+ var alert = document.getElementById('alert');
1074
+ alert.classList.remove('show');
1075
+ }
1076
+
1077
+ function copyStuffToClipboard(item,stuff) {
1078
+ if(stuff == 'name') {
1079
+ var str = item.closest('.image-item').getElementsByClassName('firstN')[0].textContent +
1080
+ ' ' + item.closest('.image-item').getElementsByClassName('lastN')[0].textContent;
1081
+ doAlert('Copied to name clipboard!');
1082
+ } else if(stuff == 'tags') {
1083
+ console.log(item);
1084
+ var str = item.textContent;
1085
+ doAlert('Copied to tags clipboard!');
1086
+ }
1087
+ navigator.clipboard.writeText(str);
1088
+ }
1089
+
1090
+ function toggleThisArtistsTags(tagsStr) {
1091
+ let names = tagsStr.split(', ');
1092
+ let allChecked = true;
1093
+ for(i=0,il=names.length;i<il;i++) {
1094
+ if(!document.querySelector('input[name="'+names[i]+'"]').checked) {
1095
+ allChecked = false;
1096
+ break;
1097
+ }
1098
+ }
1099
+ for(i=0,il=names.length;i<il;i++) {
1100
+ var checkbox = document.querySelector('input[name="'+names[i]+'"]');
1101
+ if(allChecked) {
1102
+ checkbox.checked = false;
1103
+ } else {
1104
+ checkbox.checked = true;
1105
+ }
1106
+ storeCheckboxState(checkbox);
1107
+ }
1108
+ }
1109
+
1110
+ function showHideCategories() {
1111
+ let useCategories = document.querySelectorAll('input[name="use_categories"]')[0].checked;
1112
+ let categories = document.getElementsByClassName('category');
1113
+ for(let category of categories) {
1114
+ if(useCategories) {
1115
+ category.classList.remove('hidden');
1116
+ } else {
1117
+ category.classList.add('hidden');
1118
+ }
1119
+ }
1120
+ let editLink = document.getElementById('edit_most_used');
1121
+ if(useCategories) {
1122
+ editLink.classList.remove('hidden');
1123
+ } else {
1124
+ editLink.classList.add('hidden');
1125
+ }
1126
+ }
1127
+
1128
+ function showHideLowCountTags() {
1129
+ var hideLowCount = document.querySelector('input[name="low_count"]').checked;
1130
+ var checkboxes = document.querySelectorAll('input[type="checkbox"]');
1131
+ checkboxes.forEach(function(checkbox) {
1132
+ if(hideLowCount) {
1133
+ if(checkbox.parentNode.classList.contains('category') || checkbox.parentNode.classList.contains('no_matches')) {
1134
+ // skip hide
1135
+ } else {
1136
+ let count = parseInt(checkbox.parentNode.querySelector('.count').textContent.replace(/,/g, '').trim().substring(2),10);
1137
+ if(count < 3) {
1138
+ checkbox.checked = false;
1139
+ checkbox.parentNode.classList.add('hidden');
1140
+ }
1141
+ }
1142
+ } else {
1143
+ checkbox.parentNode.classList.remove('hidden');
1144
+ }
1145
+ showHideCategories();
1146
+ });
1147
+ }
1148
+
1149
+ function loadLargerImages(imageItem) {
1150
+ let images = imageItem.querySelectorAll('img');
1151
+ let missingFiles = '';
1152
+ let imagePromises = Array.from(images).map((img) => {
1153
+ if(img.src.indexOf('_thumbs') > -1) {
1154
+ let first = img.closest('.image-item').querySelector('.firstN');
1155
+ let last = img.closest('.image-item').querySelector('.lastN');
1156
+ return new Promise((resolve, reject) => {
1157
+ img.onload = () => {
1158
+ resolve();
1159
+ }
1160
+ img.onerror = () => {
1161
+ missingFiles += '<li>' + first + '_' + last + '-artwork.webp</li>';
1162
+ reject();
1163
+ };
1164
+ img.src = img.src.replace('_thumbs','');
1165
+ });
1166
+ }
1167
+ });
1168
+ let report = document.getElementById('missing_images_report');
1169
+ if(imagePromises.length > 0) {
1170
+ Promise.allSettled(imagePromises).then(() => {
1171
+ if(missingFiles.indexOf('webp')>0) {
1172
+ report.innerHTML += missingFiles;
1173
+ }
1174
+ });
1175
+ }
1176
+ }
1177
+
1178
+ function hideLargerImageBackup(imageItem) {
1179
+ // very fast mouse movement from the thumbnail to the larger image can
1180
+ // cause the browser to fail to detect that CSS imageItem:hover is no longer true
1181
+ // therefore we need this backup, but we minimize mousemove listening
1182
+ windowWidth = window.innerWidth;
1183
+ let layout = document.getElementById('layout');
1184
+ // store a reference to the bound function, allowing it to be removed
1185
+ imageItem.boundMouseMoveFunc = mouseMoveFunc.bind(null, imageItem);
1186
+ layout.addEventListener('mousemove', imageItem.boundMouseMoveFunc);
1187
+ timer = setTimeout(function() {
1188
+ cleanupEventListener(imageItem);
1189
+ }, 200);
1190
+ }
1191
+
1192
+ function mouseMoveFunc(imageItem, e) {
1193
+ if (e.clientX < (windowWidth * 0.4)) {
1194
+ imageItem.getElementsByClassName('imgBox')[0].style.position = 'relative';
1195
+ }
1196
+ }
1197
+
1198
+ function cleanupEventListener(imageItem) {
1199
+ imageItem.getElementsByClassName('imgBox')[0].style.position = '';
1200
+ let layout = document.getElementById('layout');
1201
+ // remove the previously bound function
1202
+ layout.removeEventListener('mousemove', imageItem.boundMouseMoveFunc);
1203
+ }
1204
+
1205
+ //
1206
+ //
1207
+ //
1208
+ //
1209
+ //
1210
+ //
1211
+ //
1212
+ //
1213
+ //
1214
+ //
1215
+ //
1216
+ //
1217
+ //
1218
+ //
1219
+ //
1220
+ //
1221
+ // content loaded function
1222
+ document.addEventListener("DOMContentLoaded", function() {
1223
+ //
1224
+ //
1225
+ startUp();
1226
+ //
1227
+ //
1228
+ // add checkbox event listeners
1229
+ var checkboxes = document.querySelectorAll('input[type="checkbox"]');
1230
+ checkboxes.forEach(function(checkbox) {
1231
+ let isTop = checkbox.parentNode.classList.contains('top_control');
1232
+ if(!isTop || checkbox.name == 'favorite') {
1233
+ // normal checkboxes
1234
+ checkbox.addEventListener('change', function(e) {
1235
+ checkAllInCategory(e.target);
1236
+ hideAllArtists();
1237
+ unhideBasedOnPermissiveSetting();
1238
+ storeCheckboxState(e.target);
1239
+ updateArtistsCountPerTag('click');
1240
+ });
1241
+ } else {
1242
+ // top checkboxes
1243
+ if(checkbox.name == 'check-all') {
1244
+ checkbox.addEventListener('change', function(e) {
1245
+ checkOrUncheckAll(this.checked);
1246
+ storeCheckboxStateAll(this.checked);
1247
+ hideAllArtists();
1248
+ unhideBasedOnPermissiveSetting();
1249
+ updateArtistsCountPerTag('click');
1250
+ });
1251
+ } else if(checkbox.name == 'mode') {
1252
+ checkbox.addEventListener('change', function(e) {
1253
+ hideAllArtists();
1254
+ unhideBasedOnPermissiveSetting();
1255
+ updateArtistsCountPerTag('click');
1256
+ storeCheckboxState(e.target);
1257
+ });
1258
+ } else if(checkbox.name == 'use_categories') {
1259
+ checkbox.addEventListener('change', function(e) {
1260
+ showHideCategories();
1261
+ sortTags();
1262
+ storeCheckboxState(e.target);
1263
+ });
1264
+ } else if(checkbox.name == 'low_count') {
1265
+ checkbox.addEventListener('change', function(e) {
1266
+ showHideLowCountTags();
1267
+ storeCheckboxState(e.target);
1268
+ });
1269
+ }
1270
+ }
1271
+ });
1272
+ // add options event listeners
1273
+ var infoI = document.getElementById('infoI');
1274
+ infoI.addEventListener('click', function(e) {
1275
+ showInstructions();
1276
+ });
1277
+ var infoA = document.getElementById('infoA');
1278
+ infoA.addEventListener('click', function(e) {
1279
+ showAbout();
1280
+ });
1281
+ var infoE = document.getElementById('infoX');
1282
+ infoX.addEventListener('click', function(e) {
1283
+ showExport();
1284
+ });
1285
+ // prompt options
1286
+ var promptA = document.getElementById('promptA');
1287
+ promptA.addEventListener('click', function(e) {
1288
+ highlightSelectedOption('promptA');
1289
+ rotatePromptsImages();
1290
+ storeOptionsState();
1291
+ });
1292
+ var promptP = document.getElementById('promptP');
1293
+ promptP.addEventListener('click', function(e) {
1294
+ highlightSelectedOption('promptP');
1295
+ rotatePromptsImages();
1296
+ storeOptionsState();
1297
+ });
1298
+ var promptL = document.getElementById('promptL');
1299
+ promptL.addEventListener('click', function(e) {
1300
+ highlightSelectedOption('promptL');
1301
+ rotatePromptsImages();
1302
+ storeOptionsState();
1303
+ });
1304
+ // add information event listeners
1305
+ var export_to_clipboard = document.getElementById('export_to_clipboard');
1306
+ export_to_clipboard.addEventListener('click', function(e) {
1307
+ copyExportToClipboard();
1308
+ });
1309
+ var export_import = document.getElementById('export_import');
1310
+ export_import.addEventListener('click', function(e) {
1311
+ importFavorites();
1312
+ });
1313
+ var information = document.querySelectorAll('.information');
1314
+ information.forEach(function(element) {
1315
+ element.addEventListener('mouseleave', function(e) {
1316
+ if (!element.contains(e.relatedTarget)) {
1317
+ hideInformation();
1318
+ }
1319
+ });
1320
+ });
1321
+ // sort options
1322
+ var sortTA = document.getElementById('sortTA');
1323
+ sortTA.addEventListener('click', function(e) {
1324
+ sortTagsByAlpha();
1325
+ highlightSelectedOption('sortTA');
1326
+ storeOptionsState();
1327
+ });
1328
+ var sortTC = document.getElementById('sortTC');
1329
+ sortTC.addEventListener('click', function(e) {
1330
+ sortTagsByCount();
1331
+ highlightSelectedOption('sortTC');
1332
+ storeOptionsState();
1333
+ });
1334
+ var sortAA = document.getElementById('sortAA');
1335
+ sortAA.addEventListener('click', function(e) {
1336
+ sortArtistsByAlpha();
1337
+ highlightSelectedOption('sortAA');
1338
+ storeOptionsState();
1339
+ });
1340
+ var sortAR = document.getElementById('sortAR');
1341
+ sortAR.addEventListener('click', function(e) {
1342
+ sortArtistsByRandom();
1343
+ highlightSelectedOption('sortAR');
1344
+ storeOptionsState();
1345
+ });
1346
+ // must used mode
1347
+ var mostUsed = document.getElementById('edit_most_used');
1348
+ mostUsed.addEventListener('click', function(e) {
1349
+ enterExitEditMostUsedMode();
1350
+ });
1351
+ document.addEventListener('keydown', function(event) {
1352
+ if (event.key === 'Escape' || event.keyCode === 27) {
1353
+ // event.key for modern browsers, event.keyCode for older ones
1354
+ enterExitEditMostUsedMode('exit');
1355
+ hideInformation();
1356
+ }
1357
+ });
1358
+ var labels = document.querySelectorAll('label');
1359
+ Array.from(labels).forEach(function(label) {
1360
+ label.addEventListener('click', function(e) {
1361
+ if(editMode) {
1362
+ addRemoveIsMostUsed(this);
1363
+ storeMostUsedState(this);
1364
+ }
1365
+ });
1366
+ });
1367
+ // add artist event listeners
1368
+ var imageItems = document.getElementsByClassName('image-item');
1369
+ Array.from(imageItems).forEach(function(imageItem) {
1370
+ imageItem.addEventListener('mouseenter', function(e) {
1371
+ hideToggles();
1372
+ loadLargerImages(e.target);
1373
+ timer = setTimeout(hideLargerImageBackup.bind(this, this), 200);
1374
+ });
1375
+ imageItem.addEventListener('mouseleave', function(e) {
1376
+ showToggles();
1377
+ });
1378
+ imageItem.querySelector('.art_star').addEventListener('click', function(e) {
1379
+ addOrRemoveFavorite(this.closest('.image-item'));
1380
+ storeFavoriteState(this.closest('.image-item'));
1381
+ updateFavoritesCount();
1382
+ });
1383
+ imageItem.querySelector('.art_prev').addEventListener('click', function(e) {
1384
+ highlightSelectedOption('prev');
1385
+ rotatePromptsImages();
1386
+ storeOptionsState();
1387
+ });
1388
+ imageItem.querySelector('.art_next').addEventListener('click', function(e) {
1389
+ highlightSelectedOption('next');
1390
+ rotatePromptsImages();
1391
+ storeOptionsState();
1392
+ });
1393
+ imageItem.getElementsByTagName('h3')[0].addEventListener('click', function(e) {
1394
+ copyStuffToClipboard(this,'name');
1395
+ });
1396
+ imageItem.getElementsByTagName('h4')[0].addEventListener('click', function(e) {
1397
+ copyStuffToClipboard(this, 'tags')
1398
+ // toggleThisArtistsTags(this.textContent);
1399
+ });
1400
+ });
1401
+ // add footer event listeners
1402
+ var closeFooter = document.getElementById('close_footer');
1403
+ closeFooter.addEventListener('click', function(e) {
1404
+ document.getElementById('layout').classList.add('footerHidden');
1405
+ });
1406
+ });