Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9e4ee4f
Translated to Java.
haumacher Jan 11, 2026
f40ba52
Fixed different output for Java and JS.
haumacher Jan 11, 2026
4ce5bde
Fix cross-platform compatibility: add character 15 and match JS repla…
haumacher Jan 11, 2026
89ce1b3
Fix testEmptyString and testNullString to match JavaScript behavior
haumacher Jan 11, 2026
1fb2cbf
Remove unused empty svg-data.json file
haumacher Jan 11, 2026
afa1e15
Update SCM URLs to use HTTPS instead of git protocol
haumacher Jan 11, 2026
8716a02
Bundle LICENSE file in JAR under META-INF
haumacher Jan 11, 2026
3e85e14
Add test to generate example SVG files for manual inspection
haumacher Jan 11, 2026
ebcfe22
Add Dublin Core metadata to generated SVGs for license compliance
haumacher Jan 11, 2026
db6b5b5
Declare Dublin Core namespace locally in metadata element
haumacher Jan 11, 2026
e1f84d5
Optimized pattern.
haumacher Jan 11, 2026
b1db44b
Create pattern only once.
haumacher Jan 11, 2026
6d8f8b7
Add AvatarPart enum for type-safe part name handling
haumacher Jan 11, 2026
8f48a1e
Use AvatarPart enum throughout the codebase instead of strings
haumacher Jan 11, 2026
9467c46
Refactor SvgData to use AvatarPart enum instead of strings
haumacher Jan 11, 2026
ee620e5
Add AvatarCharacter enum to replace character ID strings
haumacher Jan 11, 2026
64273e5
Refactor ThemeData to use AvatarCharacter enum instead of strings
haumacher Jan 11, 2026
95a53fa
Dump files to compare, if test fails.
haumacher Jan 11, 2026
17a45f4
Optimized/fixed template expansion.
haumacher Jan 11, 2026
d0cabde
Refactor to use PartWithTheme value class and remove string encoding
haumacher Jan 11, 2026
e41e483
Remove redundancy between Theme enum and CharacterThemes
haumacher Jan 11, 2026
40262b2
Remove Version class and inline parameters to generate() method
haumacher Jan 11, 2026
06e364b
Clarified naming.
haumacher Jan 11, 2026
3c53b8b
Reordered, renamed, cleaned up.
haumacher Jan 11, 2026
839f8d7
Separate string-based and predefined avatar generation APIs
haumacher Jan 11, 2026
8a30279
Move render() to Avatar and rename 'string' parameter to 'id'
haumacher Jan 11, 2026
a87c462
Further cleanup.
haumacher Jan 11, 2026
b334485
To top-level classes.
haumacher Jan 11, 2026
d0e7f51
Add random avatar generation API
haumacher Jan 11, 2026
64b47ae
Further cleanup.
haumacher Jan 11, 2026
200e72e
Update documentation with JavaDoc links and fix outdated references
haumacher Jan 11, 2026
840bb52
Add seeded random avatar generation methods
haumacher Jan 11, 2026
b99cb59
Cleanup.
haumacher Jan 11, 2026
3167f6e
Add comprehensive test vectors for all pure avatars
haumacher Jan 11, 2026
626b902
Reverted inlining.
haumacher Jan 11, 2026
a4371fe
Add JavaDoc documentation for AvatarPart enum constants
haumacher Jan 11, 2026
5c7b2d2
Cleanup.
haumacher Jan 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target/
23 changes: 23 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Multiavatar</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
4 changes: 4 additions & 0 deletions .settings/org.eclipse.core.resources.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
8 changes: 8 additions & 0 deletions .settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
176 changes: 176 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

Multiavatar is a multicultural avatar generator that creates unique SVG avatars from text strings. It can generate 12,230,590,464 (48^6) unique avatars by combining different parts (environment, clothes, head, mouth, eyes, top) from 16 initial characters with 3 color themes each.

**Available Implementations:**
- **JavaScript**: Single-file, dependency-free vanilla JavaScript implementation with embedded SHA-256 library
- **Java**: Maven-based library (Java 8+) with the same functionality

## Commands

### JavaScript Commands

#### Build
```bash
npm run build
```
Creates both CommonJS and ESM distributions in the `dist/` directory by:
- Creating necessary dist folders
- Adding a package.json with `"type": "commonjs"` to dist/commonjs
- Copying multiavatar.min.js and appending appropriate module exports

### Java Commands

#### Build
```bash
mvn clean compile
```
Compiles the Java source files to `target/classes/`.

#### Test
```bash
mvn test
```
Runs all unit tests (11 test cases covering basic functionality, determinism, special characters, version forcing, etc.).

#### Package
```bash
mvn package
```
Creates a JAR file in `target/multiavatar-1.0.7.jar`.

#### Install to Local Maven Repository
```bash
mvn install
```
Installs the JAR to your local ~/.m2 repository for use in other projects.

### Development Build (SVG → JS)
```bash
cd svg
php _build.php
```
Rebuilds multiavatar.js from the SVG source files. Run this after editing `*_final.svg` files in the svg/ directory. This extracts SVG elements by class (clothes, mouth, eyes, top) from the 16 character files (00_final.svg through 15_final.svg) and injects them into multiavatar.js between the `inject_start` and `inject_end` markers.

### Testing
Open `demo.html` in a browser to test avatar generation interactively.
Open `svg/index.html` to view all 48 initial unique avatars (16 characters × 3 themes).

## Architecture

### Core Algorithm

The library converts any input string into a deterministic avatar using this flow:

1. **Hash Generation**: Input string → SHA-256 hash → first 12 digits extracted
2. **Part Selection**: Each pair of digits (0-99) maps to one of 48 variants (0-47) for each of 6 parts
3. **Theme Assignment**: The 48 variants are distributed across 16 base characters × 3 themes (A/B/C):
- 0-15: Theme A
- 16-31: Theme B
- 32-47: Theme C
4. **Color Application**: Each theme defines color palettes for parts; colors replace `#(.*?);` placeholders in SVG strings
5. **SVG Assembly**: Final SVG is assembled in order: environment → head → clothes → top → eyes → mouth

### Data Structure

**multiavatar.js** contains:
- `themes` object: Maps character IDs (00-15) → themes (A/B/C) → parts → color arrays
- `sP` object (SVG Parts): Maps character IDs → parts → SVG string templates with color placeholders
- `multiavatar(string, sansEnv, ver)` function

### The 16 Initial Characters

Each numbered 00-15 with descriptive names:
00=Robo, 01=Girl, 02=Blonde, 03=Evilnormie, 04=Country, 05=Geeknot, 06=Asian, 07=Punk, 08=Afrohair, 09=Normie Female, 10=Older, 11=Firehair, 12=Blond, 13=Ateam, 14=Rasta, 15=Meta

### SVG Source Files

Source files in `svg/`:
- `00.svg` through `15.svg`: Working files for editing
- `00_final.svg` through `15_final.svg`: Optimized SVG files (saved from Inkscape 1.0 as "Optimized SVG") used by _build.php
- Each SVG uses CSS classes to identify parts: `class="clothes"`, `class="mouth"`, `class="eyes"`, `class="top"`
- Head and environment parts use special handling in the build script

## Function Parameters

```javascript
multiavatar(string, sansEnv, ver)
```

- `string` (required): Input text that determines the avatar
- `sansEnv` (optional): If true, returns avatar without the circular background (environment part)
- `ver` (optional): Object to force a specific character/theme, e.g., `{part: '01', theme: 'A'}`

## TypeScript Support

TypeScript type definitions are included:
- `dist/commonjs/index.d.ts`
- `dist/esm/index.d.ts`

## Distribution

The package supports both CommonJS and ESM:
- CommonJS: `require('@multiavatar/multiavatar')` → dist/commonjs/index.js
- ESM: `import multiavatar from '@multiavatar/multiavatar/esm'` → dist/esm/index.js

Both built files are generated from `multiavatar.min.js` with appropriate module syntax appended.

## Design Workflow

1. Edit SVG files in svg/ directory using Inkscape or similar vector editor
2. Keep designs in grayscale (colors are applied by the script)
3. Save edited files as `*_final.svg` (Inkscape: "Save As" → "Optimized SVG")
4. Run `php svg/_build.php` to extract SVG elements and update multiavatar.js
5. Update color themes in the `themes` object in multiavatar.js if needed
6. Test changes using demo.html

## Java Implementation

### Project Structure

```
src/main/java/com/multiavatar/
├── Multiavatar.java - Main public API class
├── ThemeData.java - Color theme definitions (16 characters × 3 themes)
└── SvgData.java - SVG template strings for all character parts
```

### Usage Example

```java
import com.multiavatar.Multiavatar;

public class Example {
public static void main(String[] args) {
// Basic usage
String svg = Multiavatar.generate("Binx Bond");

// Without background circle
String svgNoBackground = Multiavatar.generate("Binx Bond", true);

// Generate predefined avatar with specific character/theme
String svgPredefined = Multiavatar.generate(Multiavatar.CharacterType.GIRL, Multiavatar.CharacterTheme.A);
}
}
```

### Architecture Notes

The Java implementation follows the same algorithm as the JavaScript version:
- **ThemeData.java**: Contains all 48 theme configurations (16 characters × 3 themes A/B/C) with color arrays for each part
- **SvgData.java**: Contains all 96 SVG template strings (16 characters × 6 parts) with color placeholders
- **Multiavatar.java**: Main class implementing the algorithm (hashing → part selection → theme assignment → color application → SVG assembly)

The Java version uses Java's built-in `MessageDigest` for SHA-256 hashing (no external dependencies except JUnit for tests).

## Important Notes

- The JavaScript library is intentionally kept as a single file (multiavatar.js) with all SVG data and logic embedded
- SHA-256 library is included inline in JavaScript; Java uses built-in MessageDigest
- Not all 12 billion combinations are visually unique (some parts like eyes/mouth are similar)
- Parts can be hidden using `"none"` as a color value in theme definitions
- The Java implementation maintains full compatibility with the JavaScript version (same input produces same SVG output)
Loading