Import version 1.2021.5

This commit is contained in:
Arnaud Roques 2021-04-25 22:59:17 +02:00
parent b56e0af316
commit fcf10ee0a9
60 changed files with 3099 additions and 540 deletions

View File

@ -91,7 +91,7 @@
<manifest>
<attribute name="Automatic-Module-Name" value="net.sourceforge.plantuml" />
<attribute name="Main-Class" value="net.sourceforge.plantuml.Run" />
<attribute name="Class-Path" value="avalon-framework-4.2.0.jar batik-all-1.7.jar commons-io-1.3.1.jar commons-logging-1.0.4.jar fop.jar xml-apis-ext-1.3.04.jar xmlgraphics-commons-1.4.jar jlatexmath-minimal-1.0.3.jar jlm_cyrillic.jar jlm_greek.jar vizjs.jar j2v8_win32_x86_64-3.1.6.jar j2v8_linux_x86_64-3.1.6.jar j2v8_macosx_x86_64-3.1.6.jar ditaa0_9.jar" />
<attribute name="Class-Path" value="elk-full.jar avalon-framework-4.2.0.jar batik-all-1.7.jar commons-io-1.3.1.jar commons-logging-1.0.4.jar fop.jar xml-apis-ext-1.3.04.jar xmlgraphics-commons-1.4.jar jlatexmath-minimal-1.0.3.jar jlm_cyrillic.jar jlm_greek.jar vizjs.jar j2v8_win32_x86_64-3.1.6.jar j2v8_linux_x86_64-3.1.6.jar j2v8_macosx_x86_64-3.1.6.jar ditaa0_9.jar" />
</manifest>
</jar>
<delete dir="build" />

17
pom.xml
View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>1.2021.5-SNAPSHOT</version>
<version>1.2021.6-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>
@ -94,21 +94,6 @@
<version>1.0.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.elk</groupId>
<artifactId>org.eclipse.elk.core</artifactId>
<version>0.7.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.elk</groupId>
<artifactId>org.eclipse.elk.alg.layered</artifactId>
<version>0.7.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.elk</groupId>
<artifactId>org.eclipse.elk.alg.mrtree</artifactId>
<version>0.7.1</version>
</dependency>
</dependencies>
<licenses>

View File

@ -290,6 +290,10 @@ ganttDiagram {
timeline {
BackgroundColor transparent
}
closed {
BackGroundColor #E0E8E8
FontColor #909898
}
task {
RoundCorner 0
Margin 2 2 2 2

View File

@ -0,0 +1,271 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Defaults.LANES_DEF;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Defaults.LOG_M_COST_DEF;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Defaults.OUTLEN_DEF;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Defaults.TYPE_DEF;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Defaults.T_COST_DEF;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Defaults.VERSION_DEF;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
import ext.plantuml.com.at.gadermaier.argon2.algorithm.FillMemory;
import ext.plantuml.com.at.gadermaier.argon2.algorithm.Finalize;
import ext.plantuml.com.at.gadermaier.argon2.algorithm.Initialize;
import ext.plantuml.com.at.gadermaier.argon2.model.Argon2Type;
import ext.plantuml.com.at.gadermaier.argon2.model.Instance;
public class Argon2 {
private byte[] output;
private int outputLength; // -l N
private double duration;
private byte[] password;
private byte[] salt;
private byte[] secret;
private byte[] additional;
private int iterations; // -t N
private int memory; // -m N
private int lanes; // -p N
private int version; // -v (10/13)
private Argon2Type type;
private boolean clearMemory = true;
private Charset charset = Charset.forName("UTF-8");
private boolean encodedOnly = false;
private boolean rawOnly = false;
Argon2() {
this.lanes = LANES_DEF;
this.outputLength = OUTLEN_DEF;
this.memory = 1 << LOG_M_COST_DEF;
this.iterations = T_COST_DEF;
this.version = VERSION_DEF;
this.type = TYPE_DEF;
}
private static byte[] toByteArray(char[] chars, Charset charset) {
assert chars != null;
CharBuffer charBuffer = CharBuffer.wrap(chars);
ByteBuffer byteBuffer = charset.encode(charBuffer);
byte[] bytes = Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
Arrays.fill(byteBuffer.array(), (byte) 0);
return bytes;
}
public void hashNow() {
try {
Validation.validateInput(this);
long start = System.nanoTime();
Instance instance = new Instance(this);
Initialize.initialize(instance, this);
FillMemory.fillMemoryBlocks(instance);
Finalize.finalize(instance, this);
duration = (System.nanoTime() - start) / 1000000000.0;
} finally {
clear();
}
}
public void clear() {
if (password != null)
Arrays.fill(password, 0, password.length - 1, (byte) 0);
if (salt != null)
Arrays.fill(salt, 0, salt.length - 1, (byte) 0);
if (secret != null)
Arrays.fill(secret, 0, secret.length - 1, (byte) 0);
if (additional != null)
Arrays.fill(additional, 0, additional.length - 1, (byte) 0);
}
void printSummary() {
if (encodedOnly)
System.out.println(getEncoded());
else if (rawOnly)
System.out.println(getOutputString());
else {
System.out.println("Type:\t\t" + type);
System.out.println("Iterations:\t" + iterations);
System.out.println("Memory:\t\t" + memory + " KiB");
System.out.println("Parallelism:\t" + lanes);
System.out.println("Hash:\t\t" + getOutputString());
System.out.println("Encoded:\t " + getEncoded());
System.out.println(duration + " seconds");
}
}
public Argon2 setMemoryInKiB(int memory) {
this.memory = memory;
return this;
}
public Argon2 setParallelism(int parallelism) {
this.lanes = parallelism;
return this;
}
public Argon2 setPassword(char[] password) {
return setPassword(toByteArray(password, charset));
}
public Argon2 setSalt(String salt) {
return setSalt(salt.getBytes(charset));
}
public byte[] getOutput() {
return output;
}
public void setOutput(byte[] finalResult) {
this.output = finalResult;
}
public String getOutputString() {
return Util.bytesToHexString(output);
}
public int getOutputLength() {
return outputLength;
}
public Argon2 setOutputLength(int outputLength) {
this.outputLength = outputLength;
return this;
}
public byte[] getPassword() {
return password;
}
public Argon2 setPassword(byte[] password) {
this.password = password;
return this;
}
public int getPasswordLength() {
return password.length;
}
public byte[] getSalt() {
return salt;
}
public Argon2 setSalt(byte[] salt) {
this.salt = salt;
return this;
}
public int getSaltLength() {
return salt.length;
}
public byte[] getSecret() {
return secret;
}
public Argon2 setSecret(byte[] secret) {
this.secret = secret;
return this;
}
public int getSecretLength() {
return secret != null ? secret.length : 0;
}
public byte[] getAdditional() {
return additional;
}
public Argon2 setAdditional(byte[] additional) {
this.additional = additional;
return this;
}
public int getAdditionalLength() {
return additional != null ? additional.length : 0;
}
public int getIterations() {
return iterations;
}
public Argon2 setIterations(int iterations) {
this.iterations = iterations;
return this;
}
public int getMemory() {
return memory;
}
public Argon2 setMemory(int memory) {
this.memory = 1 << memory;
return this;
}
public int getLanes() {
return lanes;
}
public int getVersion() {
return version;
}
public Argon2 setVersion(int version) {
this.version = version;
return this;
}
public Argon2Type getType() {
return type;
}
public Argon2 setType(Argon2Type type) {
this.type = type;
return this;
}
public boolean isClearMemory() {
return clearMemory;
}
public void setClearMemory(boolean clearMemory) {
this.clearMemory = clearMemory;
}
public Charset getCharset() {
return charset;
}
public void setEncodedOnly(boolean encodedOnly) {
this.encodedOnly = encodedOnly;
}
public void setRawOnly(boolean rawOnly) {
this.rawOnly = rawOnly;
}
public String getEncoded() {
return ""; // TODO
}
}

View File

@ -0,0 +1,12 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2;
public class Argon2Factory {
public static Argon2 create(){
return new Argon2();
}
}

View File

@ -0,0 +1,102 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2;
import ext.plantuml.com.at.gadermaier.argon2.model.Argon2Type;
public class Constants {
/* Memory block size in bytes */
public static final int ARGON2_BLOCK_SIZE = 1024;
public static final int ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8;
/* Number of pseudo-random values generated by one call to Blake in Argon2i
to
generate reference block positions
*/
public static final int ARGON2_ADDRESSES_IN_BLOCK = 128;
/* Pre-hashing digest length and its extension*/
public static final int ARGON2_PREHASH_DIGEST_LENGTH = 64;
public static final int ARGON2_PREHASH_SEED_LENGTH = 72;
/* Number of synchronization points between lanes per pass */
public static final int ARGON2_SYNC_POINTS = 4;
/* Flags to determine which fields are securely wiped (default = no wipe). */
public static final int ARGON2_DEFAULT_FLAGS = 0;
public static final int ARGON2_VERSION_10 = 0x10;
public static final int ARGON2_VERSION_13 = 0x13;
public static class Defaults {
public static final int OUTLEN_DEF = 32;
public static final int T_COST_DEF = 3;
public static final int LOG_M_COST_DEF = 12;
public static final int LANES_DEF = 1;
public static final Argon2Type TYPE_DEF = Argon2Type.Argon2i;
public static final int VERSION_DEF = ARGON2_VERSION_13;
public static final int ARGON2_VERSION_NUMBER = ARGON2_VERSION_13;
public static final boolean ENCODED_ONLY = false;
public static final boolean RAW_ONLY = false;
}
//public static int ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
//public static int ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
/*
* Argon2 input parameter restrictions
*/
public static class Constraints {
public static final int MAX_PASSWORD_LEN = 128;
/* Minimum and maximum number of lanes (degree of parallelism) */
public static final int MIN_PARALLELISM = 1;
public static final int MAX_PARALLELISM = 16777216;
/* Minimum and maximum digest size in bytes */
public static final int MIN_OUTLEN = 4;
public static final int MAX_OUTLEN = Integer.MAX_VALUE;
/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
public static final int MIN_MEMORY = (2 * ARGON2_SYNC_POINTS); /* 2 blocks per slice */
/* Minimum and maximum number of passes */
public static final int MIN_ITERATIONS = 1;
public static final int MAX_ITERATIONS = Integer.MAX_VALUE;
/* Minimum and maximum password length in bytes */
public static final int MIN_PWD_LENGTH = 0;
public static final int MAX_PWD_LENGTH = Integer.MAX_VALUE;
/* Minimum and maximum salt length in bytes */
public static final int MIN_SALT_LENGTH = 0;
public static final int MAX_SALT_LENGTH = Integer.MAX_VALUE;
/* Minimum and maximum key length in bytes */
public static final int MAX_SECRET_LENGTH = Integer.MAX_VALUE;
/* Minimum and maximum associated model length in bytes */
public static final int MAX_AD_LENGTH = Integer.MAX_VALUE;
}
public static class Messages {
public static final String P_MIN_MSG = "degree of parallelism cannot be smaller than one";
public static final String P_MAX_MSG = "parallelism cannot be greater than 16777216";
public static final String M_MIN_MSG = "memory too small";
public static final String T_MIN_MSG = "number of iterations cannot be less than one";
public static final String T_MAX_MSG = "number of iterations too high";
public static final String PWD_MIN_MSG = "password too short";
public static final String PWD_MAX_MSG = "password too long";
public static final String SALT_MIN_MSG = "salt too short";
public static final String SALT_MAX_MSG = "salt too long";
public static final String SECRET_MAX_MSG = "secret too long";
public static final String ADDITIONAL_MAX_MSG = "additional data too long";
}
}

View File

@ -0,0 +1,67 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2;
public class Util {
public static String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public static long littleEndianBytesToLong(byte[] b) {
long result = 0;
for (int i = 7; i >= 0; i--) {
result <<= 8;
result |= (b[i] & 0xFF);
}
return result;
}
public static byte[] intToLittleEndianBytes(int a) {
byte[] result = new byte[4];
result[0] = (byte) (a & 0xFF);
result[1] = (byte) ((a >> 8) & 0xFF);
result[2] = (byte) ((a >> 16) & 0xFF);
result[3] = (byte) ((a >> 24) & 0xFF);
return result;
}
public static byte[] longToLittleEndianBytes(long a) {
byte[] result = new byte[8];
result[0] = (byte) (a & 0xFF);
result[1] = (byte) ((a >> 8) & 0xFF);
result[2] = (byte) ((a >> 16) & 0xFF);
result[3] = (byte) ((a >> 24) & 0xFF);
result[4] = (byte) ((a >> 32) & 0xFF);
result[5] = (byte) ((a >> 40) & 0xFF);
result[6] = (byte) ((a >> 48) & 0xFF);
result[7] = (byte) ((a >> 56) & 0xFF);
return result;
}
public static long intToLong(int x){
byte[] intBytes = intToLittleEndianBytes(x);
byte[] bytes = new byte[8];
System.arraycopy(intBytes, 0, bytes, 0, 4);
return littleEndianBytesToLong(bytes);
}
}

View File

@ -0,0 +1,63 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MAX_AD_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MAX_ITERATIONS;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MAX_PARALLELISM;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MAX_PWD_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MAX_SALT_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MAX_SECRET_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MIN_ITERATIONS;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MIN_PARALLELISM;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MIN_PWD_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Constraints.MIN_SALT_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.ADDITIONAL_MAX_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.M_MIN_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.PWD_MAX_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.PWD_MIN_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.P_MAX_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.P_MIN_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.SALT_MAX_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.SALT_MIN_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.SECRET_MAX_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.T_MAX_MSG;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.Messages.T_MIN_MSG;
import ext.plantuml.com.at.gadermaier.argon2.exception.Argon2InvalidParameterException;
class Validation {
static void validateInput(Argon2 argon2){
String message = null;
if (argon2.getLanes() < MIN_PARALLELISM)
message = P_MIN_MSG;
else if (argon2.getLanes() > MAX_PARALLELISM)
message = P_MAX_MSG;
else if(argon2.getMemory() < 2 * argon2.getLanes())
message = M_MIN_MSG;
else if(argon2.getIterations() < MIN_ITERATIONS)
message = T_MIN_MSG;
else if(argon2.getIterations() > MAX_ITERATIONS)
message = T_MAX_MSG;
else if(argon2.getPasswordLength() < MIN_PWD_LENGTH)
message = PWD_MIN_MSG;
else if(argon2.getPasswordLength() > MAX_PWD_LENGTH)
message = PWD_MAX_MSG;
else if(argon2.getSaltLength() < MIN_SALT_LENGTH)
message = SALT_MIN_MSG;
else if(argon2.getSaltLength() > MAX_SALT_LENGTH)
message = SALT_MAX_MSG;
else if(argon2.getSecretLength() > MAX_SECRET_LENGTH)
message = SECRET_MAX_MSG;
else if(argon2.getAdditionalLength() > MAX_AD_LENGTH)
message = ADDITIONAL_MAX_MSG;
if(message != null)
throw new Argon2InvalidParameterException(message);
}
}

View File

@ -0,0 +1,55 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.algorithm;
import ext.plantuml.com.at.gadermaier.argon2.model.Block;
class FillBlock {
static void fillBlock(Block X, Block Y, Block currentBlock, boolean withXor) {
Block R = new Block();
Block Z = new Block();
R.xor(X, Y);
Z.copyBlock(R);
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
(16,17,..31)... finally (112,113,...127) */
for (int i = 0; i < 8; i++) {
Functions.roundFunction(Z,
16 * i, 16 * i + 1, 16 * i + 2,
16 * i + 3, 16 * i + 4, 16 * i + 5,
16 * i + 6, 16 * i + 7, 16 * i + 8,
16 * i + 9, 16 * i + 10, 16 * i + 11,
16 * i + 12, 16 * i + 13, 16 * i + 14,
16 * i + 15
);
}
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
for (int i = 0; i < 8; i++) {
Functions.roundFunction(Z,
2 * i, 2 * i + 1, 2 * i + 16,
2 * i + 17, 2 * i + 32, 2 * i + 33,
2 * i + 48, 2 * i + 49, 2 * i + 64,
2 * i + 65, 2 * i + 80, 2 * i + 81,
2 * i + 96, 2 * i + 97, 2 * i + 112,
2 * i + 113
);
}
if (withXor) {
currentBlock.xor(R, Z, currentBlock);
} else {
currentBlock.xor(R, Z);
}
}
}

View File

@ -0,0 +1,80 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.algorithm;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_SYNC_POINTS;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import ext.plantuml.com.at.gadermaier.argon2.model.Instance;
import ext.plantuml.com.at.gadermaier.argon2.model.Position;
public class FillMemory {
public static void fillMemoryBlocks(Instance instance) {
if (instance.getLanes() == 1) {
fillMemoryBlockSingleThreaded(instance);
} else {
fillMemoryBlockMultiThreaded(instance);
}
}
private static void fillMemoryBlockSingleThreaded(Instance instance) {
for (int i = 0; i < instance.getIterations(); i++) {
for (int j = 0; j < ARGON2_SYNC_POINTS; j++) {
Position position = new Position(i, 0, j, 0);
FillSegment.fillSegment(instance, position);
}
}
}
private static void fillMemoryBlockMultiThreaded(final Instance instance) {
ExecutorService service = Executors.newFixedThreadPool(instance.getLanes());
List<Future<?>> futures = new ArrayList<Future<?>>();
for (int i = 0; i < instance.getIterations(); i++) {
for (int j = 0; j < ARGON2_SYNC_POINTS; j++) {
for (int k = 0; k < instance.getLanes(); k++) {
final Position position = new Position(i, k, j, 0);
Future future = service.submit(new Runnable() {
@Override
public void run() {
FillSegment.fillSegment(instance, position);
}
});
futures.add(future);
}
joinThreads(instance, futures);
}
}
service.shutdownNow();
}
private static void joinThreads(Instance instance, List<Future<?>> futures) {
try {
for (Future<?> f : futures) {
f.get();
}
} catch (InterruptedException e) {
instance.clear();
throw new RuntimeException(e);
} catch (ExecutionException e) {
instance.clear();
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,170 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.algorithm;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_ADDRESSES_IN_BLOCK;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_VERSION_10;
import ext.plantuml.com.at.gadermaier.argon2.Constants;
import ext.plantuml.com.at.gadermaier.argon2.Util;
import ext.plantuml.com.at.gadermaier.argon2.model.Argon2Type;
import ext.plantuml.com.at.gadermaier.argon2.model.Block;
import ext.plantuml.com.at.gadermaier.argon2.model.Instance;
import ext.plantuml.com.at.gadermaier.argon2.model.Position;
class FillSegment {
static void fillSegment(Instance instance, Position position) {
Block addressBlock = null, inputBlock = null, zeroBlock = null;
boolean dataIndependentAddressing = isDataIndependentAddressing(instance, position);
int startingIndex = getStartingIndex(position);
int currentOffset = position.lane * instance.getLaneLength() + position.slice * instance.getSegmentLength() + startingIndex;
int prevOffset = getPrevOffset(instance, currentOffset);
if (dataIndependentAddressing) {
addressBlock = new Block();
zeroBlock = new Block();
inputBlock = new Block();
initAddressBlocks(instance, position, zeroBlock, inputBlock, addressBlock);
}
for (position.index = startingIndex; position.index < instance.getSegmentLength(); position.index++, currentOffset++, prevOffset++) {
prevOffset = rotatePrevOffset(instance, currentOffset, prevOffset);
long pseudoRandom = getPseudoRandom(instance, position, addressBlock, inputBlock, zeroBlock, prevOffset, dataIndependentAddressing);
int refLane = getRefLane(instance, position, pseudoRandom);
int refColumn = getRefColumn(instance, position, pseudoRandom, refLane == position.lane);
/* 2 Creating a new block */
Block prevBlock = instance.memory[prevOffset];
Block refBlock = instance.memory[((instance.getLaneLength()) * refLane + refColumn)];
Block currentBlock = instance.memory[currentOffset];
boolean withXor = isWithXor(instance, position);
FillBlock.fillBlock(prevBlock, refBlock, currentBlock, withXor);
}
}
private static boolean isDataIndependentAddressing(Instance instance, Position position) {
return (instance.getType() == Argon2Type.Argon2i) ||
(instance.getType() == Argon2Type.Argon2id
&& (position.pass == 0)
&& (position.slice < Constants.ARGON2_SYNC_POINTS / 2)
);
}
private static void initAddressBlocks(Instance instance, Position position, Block zeroBlock, Block inputBlock, Block addressBlock) {
inputBlock.v[0] = Util.intToLong(position.pass);
inputBlock.v[1] = Util.intToLong(position.lane);
inputBlock.v[2] = Util.intToLong(position.slice);
inputBlock.v[3] = Util.intToLong(instance.memory.length);
inputBlock.v[4] = Util.intToLong(instance.getIterations());
inputBlock.v[5] = Util.intToLong(instance.getType().ordinal());
if ((position.pass == 0) && (position.slice == 0)) {
/* Don't forget to generate the first block of addresses: */
nextAddresses(zeroBlock, inputBlock, addressBlock);
}
}
private static boolean isWithXor(Instance instance, Position position) {
return !(position.pass == 0 || instance.getVersion() == ARGON2_VERSION_10);
}
private static int getPrevOffset(Instance instance, int currentOffset) {
if (currentOffset % instance.getLaneLength() == 0) {
/* Last block in this lane */
return currentOffset + instance.getLaneLength() - 1;
} else {
/* Previous block */
return currentOffset - 1;
}
}
private static int rotatePrevOffset(Instance instance, int currentOffset, int prevOffset) {
if (currentOffset % instance.getLaneLength() == 1) {
prevOffset = currentOffset - 1;
}
return prevOffset;
}
private static int getStartingIndex(Position position) {
if ((position.pass == 0) && (position.slice == 0)) {
return 2; /* we have already generated the first two blocks */
} else {
return 0;
}
}
private static void nextAddresses(Block zeroBlock, Block inputBlock, Block addressBlock) {
inputBlock.v[6]++;
FillBlock.fillBlock(zeroBlock, inputBlock, addressBlock, false);
FillBlock.fillBlock(zeroBlock, addressBlock, addressBlock, false);
}
/* 1.2 Computing the index of the reference block */
/* 1.2.1 Taking pseudo-random value from the previous block */
private static long getPseudoRandom(Instance instance, Position position, Block addressBlock, Block inputBlock, Block zeroBlock, int prevOffset, boolean dataIndependentAddressing) {
if (dataIndependentAddressing) {
if (position.index % ARGON2_ADDRESSES_IN_BLOCK == 0) {
nextAddresses(zeroBlock, inputBlock, addressBlock);
}
return addressBlock.v[position.index % ARGON2_ADDRESSES_IN_BLOCK];
} else {
return instance.memory[prevOffset].v[0];
}
}
private static int getRefLane(Instance instance, Position position, long pseudoRandom) {
int refLane = (int) (((pseudoRandom >>> 32)) % instance.getLanes());
if ((position.pass == 0) && (position.slice == 0)) {
/* Can not reference other lanes yet */
refLane = position.lane;
}
return refLane;
}
private static int getRefColumn(Instance instance, Position position, long pseudoRandom,
boolean sameLane) {
int referenceAreaSize;
int startPosition;
if (position.pass == 0) {
startPosition = 0;
if (sameLane) {
/* The same lane => add current segment */
referenceAreaSize = position.slice * instance.getSegmentLength() + position.index - 1;
} else {
/* pass == 0 && !sameLane => position.slice > 0*/
referenceAreaSize = position.slice * instance.getSegmentLength() + ((position.index == 0) ? (-1) : 0);
}
} else {
startPosition = ((position.slice + 1) * instance.getSegmentLength()) % instance.getLaneLength();
if (sameLane) {
referenceAreaSize = instance.getLaneLength() - instance.getSegmentLength() + position.index - 1;
} else {
referenceAreaSize = instance.getLaneLength() - instance.getSegmentLength() + ((position.index == 0) ? (-1) : 0);
}
}
long relativePosition = pseudoRandom & 0xFFFFFFFFL;
// long relativePosition = pseudoRandom << 32 >>> 32;
relativePosition = (relativePosition * relativePosition) >>> 32;
relativePosition = referenceAreaSize - 1 - (referenceAreaSize * relativePosition >>> 32);
return (int) (startPosition + relativePosition) % instance.getLaneLength();
}
}

View File

@ -0,0 +1,34 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.algorithm;
import ext.plantuml.com.at.gadermaier.argon2.Argon2;
import ext.plantuml.com.at.gadermaier.argon2.model.Block;
import ext.plantuml.com.at.gadermaier.argon2.model.Instance;
public class Finalize {
public static void finalize(Instance instance, Argon2 argon2) {
Block finalBlock = instance.memory[instance.getLaneLength() - 1];
/* XOR the last blocks */
for (int i = 1; i < instance.getLanes(); i++) {
int lastBlockInLane = i * instance.getLaneLength() + (instance.getLaneLength() - 1);
finalBlock.xorWith(instance.memory[lastBlockInLane]);
}
byte[] finalBlockBytes = finalBlock.toBytes();
byte[] finalResult = Functions.blake2bLong(finalBlockBytes, argon2.getOutputLength());
argon2.setOutput(finalResult);
if (argon2.isClearMemory()) {
instance.clear();
argon2.clear();
}
}
}

View File

@ -0,0 +1,172 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.algorithm;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_BLOCK_SIZE;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_PREHASH_DIGEST_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_PREHASH_SEED_LENGTH;
import ext.plantuml.com.at.gadermaier.argon2.Util;
import ext.plantuml.com.at.gadermaier.argon2.blake2.Blake2b;
import ext.plantuml.com.at.gadermaier.argon2.model.Block;
class Functions {
/**
* H0 = H64(p, τ, m, t, v, y, |P|, P, |S|, S, |L|, K, |X|, X)
* -> 64 byte (ARGON2_PREHASH_DIGEST_LENGTH)
*/
static byte[] initialHash(byte[] lanes, byte[] outputLength,
byte[] memory, byte[] iterations,
byte[] version, byte[] type,
byte[] passwordLength, byte[] password,
byte[] saltLength, byte[] salt,
byte[] secretLength, byte[] secret,
byte[] additionalLength, byte[] additional) {
Blake2b.Param params = new Blake2b.Param()
.setDigestLength(ARGON2_PREHASH_DIGEST_LENGTH);
final Blake2b blake2b = Blake2b.Digest.newInstance(params);
blake2b.update(lanes);
blake2b.update(outputLength);
blake2b.update(memory);
blake2b.update(iterations);
blake2b.update(version);
blake2b.update(type);
blake2b.update(passwordLength);
if (password != null) {
blake2b.update(password);
}
blake2b.update(saltLength);
if (salt != null) {
blake2b.update(salt);
}
blake2b.update(secretLength);
if (secret != null) {
blake2b.update(secret);
}
blake2b.update(additionalLength);
if (additional != null) {
blake2b.update(additional);
}
byte[] blake2hash = blake2b.digest();
assert (blake2hash.length == 64);
return blake2hash;
}
/**
* H' - blake2bLong - variable length hash function
*/
static byte[] blake2bLong(byte[] input, int outputLength) {
assert (input.length == ARGON2_PREHASH_SEED_LENGTH || input.length == ARGON2_BLOCK_SIZE);
byte[] result = new byte[outputLength];
byte[] outlenBytes = Util.intToLittleEndianBytes(outputLength);
int blake2bLength = 64;
if (outputLength <= blake2bLength) {
result = blake2b(input, outlenBytes, outputLength);
} else {
byte[] outBuffer;
/* V1 */
outBuffer = blake2b(input, outlenBytes, blake2bLength);
System.arraycopy(outBuffer, 0, result, 0, blake2bLength / 2);
int r = (outputLength / 32) + (outputLength % 32 == 0 ? 0 : 1) - 2;
int position = blake2bLength / 2;
for (int i = 2; i <= r; i++, position += blake2bLength / 2) {
/* V2 to Vr */
outBuffer = blake2b(outBuffer, null, blake2bLength);
System.arraycopy(outBuffer, 0, result, position, blake2bLength / 2);
}
int lastLength = outputLength - 32 * r;
/* Vr+1 */
outBuffer = blake2b(outBuffer, null, lastLength);
System.arraycopy(outBuffer, 0, result, position, lastLength);
}
assert (result.length == outputLength);
return result;
}
private static byte[] blake2b(byte[] input, byte[] outlenBytes, int outputLength) {
Blake2b.Param params = new Blake2b.Param()
.setDigestLength(outputLength);
final Blake2b blake2b = Blake2b.Digest.newInstance(params);
if (outlenBytes != null)
blake2b.update(outlenBytes);
blake2b.update(input);
return blake2b.digest();
}
static void roundFunction(Block block,
int v0, int v1, int v2, int v3,
int v4, int v5, int v6, int v7,
int v8, int v9, int v10, int v11,
int v12, int v13, int v14, int v15) {
F(block, v0, v4, v8, v12);
F(block, v1, v5, v9, v13);
F(block, v2, v6, v10, v14);
F(block, v3, v7, v11, v15);
F(block, v0, v5, v10, v15);
F(block, v1, v6, v11, v12);
F(block, v2, v7, v8, v13);
F(block, v3, v4, v9, v14);
}
private static void F(Block block, int a, int b, int c, int d) {
fBlaMka(block, a, b);
rotr64(block, d, a, 32);
fBlaMka(block, c, d);
rotr64(block, b, c, 24);
fBlaMka(block, a, b);
rotr64(block, d, a, 16);
fBlaMka(block, c, d);
rotr64(block, b, c, 63);
}
/*designed by the Lyra PHC team */
/* a <- a + b + 2*aL*bL
* + == addition modulo 2^64
* aL = least 32 bit */
private static void fBlaMka(Block block, int x, int y) {
final long m = 0xFFFFFFFFL;
final long xy = (block.v[x] & m) * (block.v[y] & m);
block.v[x] = block.v[x] + block.v[y] + 2 * xy;
}
private static void rotr64(Block block, int v, int w, long c) {
final long temp = block.v[v] ^ block.v[w];
block.v[v] = (temp >>> c) | (temp << (64 - c));
}
}

View File

@ -0,0 +1,75 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.algorithm;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_BLOCK_SIZE;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_PREHASH_DIGEST_LENGTH;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_PREHASH_SEED_LENGTH;
import ext.plantuml.com.at.gadermaier.argon2.Argon2;
import ext.plantuml.com.at.gadermaier.argon2.Util;
import ext.plantuml.com.at.gadermaier.argon2.model.Instance;
public class Initialize {
public static void initialize(Instance instance, Argon2 argon2) {
byte[] initialHash = Functions.initialHash(
Util.intToLittleEndianBytes(argon2.getLanes()),
Util.intToLittleEndianBytes(argon2.getOutputLength()),
Util.intToLittleEndianBytes(argon2.getMemory()),
Util.intToLittleEndianBytes(argon2.getIterations()),
Util.intToLittleEndianBytes(argon2.getVersion()),
Util.intToLittleEndianBytes(argon2.getType().ordinal()),
Util.intToLittleEndianBytes(argon2.getPasswordLength()),
argon2.getPassword(),
Util.intToLittleEndianBytes(argon2.getSaltLength()),
argon2.getSalt(),
Util.intToLittleEndianBytes(argon2.getSecretLength()),
argon2.getSecret(),
Util.intToLittleEndianBytes(argon2.getAdditionalLength()),
argon2.getAdditional()
);
fillFirstBlocks(instance, initialHash);
}
/**
* (H0 || 0 || i) 72 byte -> 1024 byte
* (H0 || 1 || i) 72 byte -> 1024 byte
*/
private static void fillFirstBlocks(Instance instance, byte[] initialHash) {
final byte[] zeroBytes = {0, 0, 0, 0};
final byte[] oneBytes = {1, 0, 0, 0};
byte[] initialHashWithZeros = getInitialHashLong(initialHash, zeroBytes);
byte[] initialHashWithOnes = getInitialHashLong(initialHash, oneBytes);
for (int i = 0; i < instance.getLanes(); i++) {
byte[] iBytes = Util.intToLittleEndianBytes(i);
System.arraycopy(iBytes, 0, initialHashWithZeros, ARGON2_PREHASH_DIGEST_LENGTH + 4, 4);
System.arraycopy(iBytes, 0, initialHashWithOnes, ARGON2_PREHASH_DIGEST_LENGTH + 4, 4);
byte[] blockhashBytes = Functions.blake2bLong(initialHashWithZeros, ARGON2_BLOCK_SIZE);
instance.memory[i * instance.getLaneLength() + 0].fromBytes(blockhashBytes);
blockhashBytes = Functions.blake2bLong(initialHashWithOnes, ARGON2_BLOCK_SIZE);
instance.memory[i * instance.getLaneLength() + 1].fromBytes(blockhashBytes);
}
}
private static byte[] getInitialHashLong(byte[] initialHash, byte[] appendix) {
byte[] initialHashLong = new byte[ARGON2_PREHASH_SEED_LENGTH];
System.arraycopy(initialHash, 0, initialHashLong, 0, ARGON2_PREHASH_DIGEST_LENGTH);
System.arraycopy(appendix, 0, initialHashLong, ARGON2_PREHASH_DIGEST_LENGTH, 4);
return initialHashLong;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.exception;
/* dislike checked exceptions */
class Argon2Exception extends RuntimeException {
Argon2Exception(String message) {
super(message);
}
}

View File

@ -0,0 +1,12 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.exception;
public class Argon2InvalidParameterException extends Argon2Exception{
public Argon2InvalidParameterException(String message) {
super(message);
}
}

View File

@ -0,0 +1,10 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.model;
public enum Argon2Type {
Argon2d, Argon2i, Argon2id;
}

View File

@ -0,0 +1,81 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.model;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_BLOCK_SIZE;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_QWORDS_IN_BLOCK;
import java.util.Arrays;
import ext.plantuml.com.at.gadermaier.argon2.Util;
public class Block {
/* 128 * 8 Byte QWords */
public long[] v;
public Block() {
v = new long[ARGON2_QWORDS_IN_BLOCK];
}
public void fromBytes(byte[] input) {
assert (input.length == ARGON2_BLOCK_SIZE);
for (int i = 0; i < v.length; i++) {
byte[] slice = Arrays.copyOfRange(input, i * 8, (i + 1) * 8);
v[i] = Util.littleEndianBytesToLong(slice);
}
}
public byte[] toBytes() {
byte[] result = new byte[ARGON2_BLOCK_SIZE];
for (int i = 0; i < v.length; i++) {
byte[] bytes = Util.longToLittleEndianBytes(v[i]);
System.arraycopy(bytes, 0, result, i * bytes.length, bytes.length);
}
return result;
}
public void copyBlock(Block other) {
System.arraycopy(other.v, 0, v, 0, v.length);
}
public void xor(Block b1, Block b2) {
for (int i = 0; i < v.length; i++) {
v[i] = b1.v[i] ^ b2.v[i];
}
}
public void xor(Block b1, Block b2, Block b3) {
for (int i = 0; i < v.length; i++) {
v[i] = b1.v[i] ^ b2.v[i] ^ b3.v[i];
}
}
public void xorWith(Block other) {
for (int i = 0; i < v.length; i++) {
v[i] = v[i] ^ other.v[i];
}
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (long value : v) {
result.append(Util.bytesToHexString(Util.longToLittleEndianBytes(value)));
}
return result.toString();
}
void clear() {
Arrays.fill(v, 0);
}
}

View File

@ -0,0 +1,88 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.model;
import static ext.plantuml.com.at.gadermaier.argon2.Constants.ARGON2_SYNC_POINTS;
import ext.plantuml.com.at.gadermaier.argon2.Argon2;
public class Instance {
public Block[] memory;
private int version;
private int iterations;
private int segmentLength;
private int laneLength;
private int lanes;
private Argon2Type type;
public Instance(Argon2 argon2) {
this.version = argon2.getVersion();
this.iterations = argon2.getIterations();
this.lanes = argon2.getLanes();
this.type = argon2.getType();
/* 2. Align memory size */
/* Minimum memoryBlocks = 8L blocks, where L is the number of lanes */
int memoryBlocks = argon2.getMemory();
if (memoryBlocks < 2 * ARGON2_SYNC_POINTS * argon2.getLanes()) {
memoryBlocks = 2 * ARGON2_SYNC_POINTS * argon2.getLanes();
}
this.segmentLength = memoryBlocks / (argon2.getLanes() * ARGON2_SYNC_POINTS);
this.laneLength = segmentLength * ARGON2_SYNC_POINTS;
/* Ensure that all segments have equal length */
memoryBlocks = segmentLength * (argon2.getLanes() * ARGON2_SYNC_POINTS);
initMemory(memoryBlocks);
}
private void initMemory(int memoryBlocks) {
this.memory = new Block[memoryBlocks];
for (int i = 0; i < memory.length; i++) {
memory[i] = new Block();
}
}
public void clear() {
for (Block b : memory) {
b.clear();
}
memory = null;
}
public Block[] getMemory() {
return memory;
}
public int getVersion() {
return version;
}
public int getIterations() {
return iterations;
}
public int getSegmentLength() {
return segmentLength;
}
public int getLaneLength() {
return laneLength;
}
public int getLanes() {
return lanes;
}
public Argon2Type getType() {
return type;
}
}

View File

@ -0,0 +1,22 @@
/* This file is taken from
https://github.com/andreas1327250/argon2-java
Original Author: Andreas Gadermaier <up.gadermaier@gmail.com>
*/
package ext.plantuml.com.at.gadermaier.argon2.model;
public class Position {
public int pass;
public int lane;
public int slice;
public int index;
public Position(int pass, int lane, int slice, int index) {
this.pass = pass;
this.lane = lane;
this.slice = slice;
this.index = index;
}
}

View File

@ -1,104 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.dedication;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
public class DecoderInputStream extends InputStream {
private final TurningBytes message;
private final TurningBytes sha;
private final Random rnd;
private final InputStream source;
public DecoderInputStream(InputStream source, String s) {
this.source = source;
try {
final byte[] text = s.getBytes("UTF-8");
final byte[] key = getSignatureSha512(text);
this.rnd = new Random(getSeed(key));
this.message = new TurningBytes(text);
this.sha = new TurningBytes(key);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
}
}
private static byte[] getSignatureSha512(byte[] bytes) {
try {
final MessageDigest msgDigest = MessageDigest.getInstance("SHA-512");
msgDigest.update(bytes);
return msgDigest.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
}
}
private long getSeed(byte[] bytes) {
long result = 17;
for (byte b : bytes) {
result = result * 37 + b;
}
return result;
}
private byte getNextByte() {
return (byte) (rnd.nextInt() ^ message.nextByte() ^ sha.nextByte());
}
@Override
public void close() throws IOException {
source.close();
}
@Override
public int read() throws IOException {
int b = source.read();
if (b == -1) {
return -1;
}
b = (b ^ getNextByte()) & 0xFF;
return b;
}
}

View File

@ -36,69 +36,16 @@
package net.sourceforge.plantuml.dedication;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.math.BigInteger;
import javax.imageio.stream.ImageInputStream;
public interface Dedication {
import net.sourceforge.plantuml.security.ImageIO;
public class Dedication {
private final String name;
public static final int SIZE = 512;
public Dedication(String name) {
this.name = name;
}
static public final BigInteger E = new BigInteger("47");
static public final BigInteger N = new BigInteger(
"64194259632025692228025828504368542164501926620236990850309916606915924860847417702229807236946186163298479808527077315212362810246237044147835839820235668271044023359607622658694578433933680627840319408427732468918341837133798296090069295727323673222224923200718714534955390633175683720810506099934813509605263799234445827953809462431871169282281822048299576307847441008670575692934434087522877910989584374673170522742162366773143807761599862833698229067475807108264396251702152180676841544743258182370105404479387062985271422237607462447989728490398294623785717593446941673706569352249533885603771123718557406286501161336667835919957553680522213067630956498293529840163155604109185561515875171125161872265975088797712442352939352686113608345330266855433849127812528823634773975825170679786399199082599910532761710473383280738663105826045325480095451410448217715495894688594898541182351588505292424154550388343455540760277051977859647543838445735549451966254020972172982014944475678385523833120793348365125754234511467512831686599126674298367512469557219326026525667529348508876650236597163509336304607610284488623800062157659286940214435134423619711736992281071131245654755167288438258292694799131521268600284444731890784171372171309");
public InputStream getInputStream(String keepLetter) throws IOException {
final InputStream tmp = PSystemDedication.class.getResourceAsStream(name + ".png");
final InputStream step1 = new DecoderInputStream(tmp, keepLetter);
final QBlocks rsa = QBlocks.readFrom(step1, SIZE + 1);
final QBlocks decrypted = rsa.change(E, N);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
decrypted.writeTo(baos, SIZE);
baos.close();
return new ByteArrayInputStream(baos.toByteArray());
}
public static BufferedImage getBufferedImage(InputStream is) {
try {
final Class<?> clVP8Decoder = Class.forName("net.sourceforge.plantuml.webp.VP8Decoder");
final Object vp8Decoder = clVP8Decoder.newInstance();
// final VP8Decoder vp8Decoder = new VP8Decoder();
final Method decodeFrame = clVP8Decoder.getMethod("decodeFrame", ImageInputStream.class);
final ImageInputStream iis = ImageIO.createImageInputStream(is);
decodeFrame.invoke(vp8Decoder, iis);
// vp8Decoder.decodeFrame(iis);
iis.close();
final Object frame = clVP8Decoder.getMethod("getFrame").invoke(vp8Decoder);
return (BufferedImage) frame.getClass().getMethod("getBufferedImage").invoke(frame);
// final VP8Frame frame = vp8Decoder.getFrame();
// return frame.getBufferedImage();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public BufferedImage getBufferedImage(String keepLetter) {
try {
final InputStream is = getInputStream(keepLetter);
return getBufferedImage(is);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public BufferedImage getImage(String sentence);
}

View File

@ -0,0 +1,119 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.dedication;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import net.sourceforge.plantuml.utils.MTRandom;
public class DedicationCrypted implements Dedication {
private final String argon2;
private final BigInteger pq;
private final byte crypted[];
private final int tinyHash;
private String solution;
private long next = 0L;
public DedicationCrypted(byte crypted[], int tinyHash, String argon2, BigInteger pq) {
this.crypted = crypted;
this.pq = pq;
this.argon2 = argon2;
this.tinyHash = tinyHash;
}
public synchronized BufferedImage getImage(final String sentence) {
if (sentence.length() < 40) {
return null;
}
try {
if (solution == null || sentence.equals(this.solution) == false) {
if (System.currentTimeMillis() < next) {
return null;
}
final int tinyHash = Noise.shortHash(sentence.getBytes("UTF-8"), N.toByteArray());
if (this.tinyHash != tinyHash) {
return null;
}
this.next = System.currentTimeMillis() + 5000L;
}
final byte[] hash1 = Noise.computeArgon2bytes(sentence.getBytes("UTF-8"),
(pq.toString(35) + sentence).getBytes("UTF-8"));
final byte[] hash2 = Noise.computeArgon2bytes(sentence.getBytes("UTF-8"),
(pq.toString(36) + sentence).getBytes("UTF-8"));
final BlumBlumShub rndBBS = new BlumBlumShub(pq, hash1);
final MTRandom rndMT = new MTRandom(hash2);
byte[] current = crypted.clone();
Noise.shuffle(current, rndMT);
Noise.xor(current, rndBBS);
Noise.xor(current, sentence.getBytes("UTF-8"));
Noise.shuffle(current, rndMT);
final RBlocks init = RBlocks.readFrom(current, 513);
final RBlocks decoded = init.change(E, N);
current = decoded.toByteArray(512);
Noise.shuffle(current, rndMT);
Noise.xor(current, rndBBS);
final String argon = Noise.computeArgon2String(current, (pq.toString(34) + sentence).getBytes("UTF-8"));
if (this.argon2.equals(argon) == false) {
return null;
}
Noise.shuffle(current, rndMT);
current = Noise.reverse(current, rndMT.nextInt());
final BufferedImage img = PSystemDedication.getBufferedImage(new ByteArrayInputStream(current));
this.solution = sentence;
return img;
} catch (Throwable t) {
t.printStackTrace();
return null;
}
}
}

View File

@ -35,38 +35,41 @@
*/
package net.sourceforge.plantuml.dedication;
import java.io.IOException;
import java.io.InputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import net.sourceforge.plantuml.utils.MTRandom;
public class DedicationSimple implements Dedication {
public class NoisyInputStream extends InputStream {
private final byte crypted[];
private final String sentence;
private final MTRandom rnd;
private final InputStream source;
public NoisyInputStream(InputStream source, byte[] pass) {
this.source = source;
this.rnd = new MTRandom(pass);
public DedicationSimple(byte crypted[], String sentence) {
this.crypted = crypted;
this.sentence = sentence;
}
private byte getNextByte() {
return (byte) rnd.nextInt();
}
@Override
public void close() throws IOException {
source.close();
}
@Override
public int read() throws IOException {
int b = source.read();
if (b == -1) {
return -1;
public synchronized BufferedImage getImage(String sentence) {
if (same(this.sentence, sentence) == false) {
return null;
}
b = (b ^ getNextByte()) & 0xFF;
return b;
try {
byte[] current = crypted.clone();
final RBlocks init = RBlocks.readFrom(current, 513);
final RBlocks decoded = init.change(E, N);
current = decoded.toByteArray(512);
return PSystemDedication.getBufferedImage(new ByteArrayInputStream(current));
} catch (Throwable t) {
t.printStackTrace();
return null;
}
}
private boolean same(String s1, String s2) {
s1 = s1.replaceAll("[^\\p{L}0-9]+", "");
s2 = s2.replaceAll("[^\\p{L}0-9]+", "");
return s1.equalsIgnoreCase(s2);
}
}

View File

@ -35,79 +35,60 @@
*/
package net.sourceforge.plantuml.dedication;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.SignatureUtils;
import net.sourceforge.plantuml.FileUtils;
public class Dedications {
private static final Map<String, Dedication> normal = new HashMap<String, Dedication>();
private static final Map<String, Dedication> crypted = new HashMap<String, Dedication>();
private static final List<Dedication> all = new ArrayList<Dedication>();
static {
addNormal("Write your own dedication!", "dedication");
addNormal("linux_china", "linux_china");
addNormal("ARKBAN", "arkban");
addNormal("Boundaries allow discipline to create true strength", "boundaries");
addNormal("Thank you, Dr. Chet. I wouldn't be where I am without you", "dr_chet");
addNormal("Ben and Jen 2020", "ben");
addCrypted("0", "pOhci6rKgPXw32AeYXhOpSY0suoauHq5VUSwFqHLHsLYgSO6WaJ7BW5vtHBAoU6ePbcW7d8Flx99MWjPSKQTDm00");
addCrypted("1", "LTxN3hdnhSJ515qcA7IQ841axt4GXfUd3n2wgNirYCdLnyX2360Gv1OEOnJ1-gwFzRW5B3HAqLBkR6Ge0WW_Z000");
addCrypted("2", "lZqLduj4j1yRqSfAvkhbqVpqK8diklatiFeenDUXSdna9bKYQTzdS264YfUBScUVDYCp2Vcq04updoN98RwxE000");
try {
all.add(new DedicationSimple(load("dedication"), "Write your own dedication!"));
all.add(new DedicationSimple(load("linux_china"), "linux_china"));
all.add(new DedicationSimple(load("arkban"), "arkban"));
all.add(new DedicationSimple(load("boundaries"), "Boundaries allow discipline to create true strength"));
all.add(new DedicationSimple(load("dr_chet"), "Thank you, Dr. Chet. I wouldn't be where I am without you"));
all.add(new DedicationSimple(load("ben"), "Ben and Jen 2020"));
all.add(secret(5, "835ff5d643b58cd35a20db6480071d05751aa6a0e01da78662ceafd0161f3f5e", new BigInteger(
"1182423723677118831606503500858825217076578422970565964857326298418401529955036896808663335300684244453386039908536275400945824932191521017102701344437753036730900076162922741167523337650578479960119614237031234925702200473053235777")));
all.add(secret(3, "514816d583044efbd336882227deb822194ff63e3bdc3cf707a01f17770d5a6a", new BigInteger(
"538955952645999836068094511687012232127213955837942782605199622268460518023083462090291844640318324475656060087513198129259364840841077651829017347845508167869708224054456044836844382437974410757740941102771969965334031780041648873")));
} catch (IOException e) {
e.printStackTrace();
}
}
private static void addNormal(String sentence, String name) {
normal.put(keepLetter(sentence), new Dedication(name));
private static DedicationCrypted secret(int tiny, String sig, BigInteger pq) throws IOException {
return new DedicationCrypted(load(sig), tiny, sig, pq);
}
private static void addCrypted(String name, String contentKey) {
crypted.put(contentKey, new Dedication(name));
private static byte[] load(String name) throws IOException {
final InputStream tmp = PSystemDedication.class.getResourceAsStream(name + ".png");
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileUtils.copyInternal(tmp, baos, true);
return baos.toByteArray();
}
private Dedications() {
}
public static Dedication get(String line) {
final String keepLetter = keepLetter(line);
final Dedication result = normal.get(keepLetter);
if (result != null) {
return result;
}
for (Map.Entry<String, Dedication> ent : crypted.entrySet()) {
final Dedication dedication = ent.getValue();
InputStream is = null;
try {
is = dedication.getInputStream(keepLetter);
final String signature = SignatureUtils.getSignatureSha512(is);
if (signature.equals(ent.getKey())) {
return dedication;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
public synchronized static BufferedImage get(String line) {
for (Dedication dedication : all) {
final BufferedImage image = dedication.getImage(line);
if (image != null) {
return image;
}
}
return null;
}
public static String keepLetter(String s) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
final char c = s.charAt(i);
if (Character.isLetterOrDigit(c)) {
sb.append(c);
}
}
return sb.toString();
}
}

View File

@ -35,6 +35,80 @@
*/
package net.sourceforge.plantuml.dedication;
import ext.plantuml.com.at.gadermaier.argon2.Argon2;
import ext.plantuml.com.at.gadermaier.argon2.Argon2Factory;
import ext.plantuml.com.at.gadermaier.argon2.model.Argon2Type;
import net.sourceforge.plantuml.utils.MTRandom;
public class Noise {
private static Argon2 argon2(byte[] buffer, byte[] salt) {
final Argon2 argon = Argon2Factory.create() //
.setType(Argon2Type.Argon2id) //
.setMemory(8) //
.setSalt(salt.clone()) //
.setIterations(50) //
.setPassword(buffer.clone());
argon.hashNow();
return argon;
}
public static String computeArgon2String(byte[] buffer, byte[] salt) {
return argon2(buffer, salt).getOutputString();
}
public static byte[] computeArgon2bytes(byte[] buffer, byte[] salt) {
return argon2(buffer, salt).getOutput();
}
public static int shortHash(byte[] buffer, byte[] salt) {
final byte hash[] = argon2(buffer, salt).getOutput();
int result = 0;
for (byte b : hash) {
final int b1 = b & 0x0F;
final int b2 = (b & 0xF0) >> 4;
result ^= b1 ^ b2;
}
return result;
}
public static void shuffle(byte[] buffer, MTRandom rnd) {
for (int i = 0; i < buffer.length; i++) {
final int r1 = rnd.nextInt();
final int r2 = rnd.nextInt();
final int a = Math.abs(r1) % buffer.length;
final int b = Math.abs(r2) % buffer.length;
final byte tmp = buffer[a];
buffer[a] = buffer[b];
buffer[b] = tmp;
}
}
public static void xor(byte[] buffer, byte[] xor) {
for (int i = 0; i < buffer.length; i++) {
buffer[i] ^= xor[i % xor.length];
}
}
public static void xor(byte[] buffer, BlumBlumShub rnd) {
for (int i = 0; i < buffer.length; i++) {
final byte mask = (byte) (rnd.nextRnd(8) & 0xFF);
buffer[i] = (byte) (buffer[i] ^ mask);
}
}
public static byte[] reverse(byte[] buffer, int delta) {
delta = Math.abs(delta) % buffer.length;
final byte result[] = new byte[buffer.length];
for (int i = 0; i < buffer.length; i++)
result[i] = buffer[(buffer.length - 1 - i + delta) % buffer.length];
return result;
}
}

View File

@ -53,22 +53,20 @@ import net.sourceforge.plantuml.ugraphic.UImage;
public class PSystemDedication extends PlainDiagram {
private final Dedication dedication;
private final String keepLetter;
private final BufferedImage img;
public PSystemDedication(Dedication dedication, String keepLetter) {
this.dedication = dedication;
this.keepLetter = keepLetter;
public PSystemDedication(BufferedImage img) {
this.img = img;
if (img == null) {
throw new IllegalArgumentException();
}
}
@Override
protected UDrawable getRootDrawable(FileFormatOption fileFormatOption) {
return new UDrawable() {
public void drawU(UGraphic ug) {
final BufferedImage bufferedImage = dedication.getBufferedImage(keepLetter);
if (bufferedImage != null) {
ug.draw(new UImage(new PixelImage(bufferedImage, AffineTransformType.TYPE_BILINEAR)));
}
ug.draw(new UImage(new PixelImage(img, AffineTransformType.TYPE_BILINEAR)));
}
};
}

View File

@ -35,6 +35,8 @@
*/
package net.sourceforge.plantuml.dedication;
import java.awt.image.BufferedImage;
import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.command.PSystemSingleLineFactory;
@ -42,9 +44,9 @@ public class PSystemDedicationFactory extends PSystemSingleLineFactory {
@Override
protected AbstractPSystem executeLine(String line) {
final Dedication dedication = Dedications.get(line);
final BufferedImage dedication = Dedications.get(line);
if (dedication != null) {
return new PSystemDedication(dedication, Dedications.keepLetter(line));
return new PSystemDedication(dedication);
}
return null;
}

View File

@ -271,25 +271,30 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private TimeHeader getTimeHeader() {
if (openClose.getCalendar() == null) {
return new TimeHeaderSimple(min, max);
return new TimeHeaderSimple(min, max, getClosedStyle(), getIHtmlColorSet());
} else if (printScale == PrintScale.WEEKLY) {
return new TimeHeaderWeekly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
colorDaysOfWeek, weekNumberStrategy);
colorDaysOfWeek, weekNumberStrategy, getClosedStyle(), getIHtmlColorSet());
} else if (printScale == PrintScale.MONTHLY) {
return new TimeHeaderMonthly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
colorDaysOfWeek);
colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet());
} else if (printScale == PrintScale.QUARTERLY) {
return new TimeHeaderQuarterly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
colorDaysOfWeek);
colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet());
} else if (printScale == PrintScale.YEARLY) {
return new TimeHeaderYearly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
colorDaysOfWeek);
colorDaysOfWeek, getClosedStyle(), getIHtmlColorSet());
} else {
return new TimeHeaderDaily(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
nameDays, printStart, printEnd);
nameDays, printStart, printEnd, getClosedStyle(), getIHtmlColorSet());
}
}
private Style getClosedStyle() {
return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.closed)
.getMergedStyle(getCurrentStyleBuilder());
}
private double getTotalHeight(TimeHeader timeHeader) {
if (showFootbox) {
return totalHeightWithoutFooter + timeHeader.getTimeFooterHeight();

View File

@ -42,6 +42,8 @@ import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UFont;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
@ -62,17 +64,30 @@ public abstract class TimeHeader {
return 28;
}
protected final HColor veryLightGray = HColorSet.instance().getColorOrWhite("#E0E8E8");
protected final HColor lightGray = HColorSet.instance().getColorOrWhite("#909898");
private final TimeScale timeScale;
private final Style style;
private final HColorSet colorSet;
protected final Day min;
protected final Day max;
public TimeHeader(Day min, Day max, TimeScale timeScale) {
public TimeHeader(Day min, Day max, TimeScale timeScale, Style style, HColorSet colorSet) {
if (style == null) {
throw new IllegalArgumentException();
}
this.timeScale = timeScale;
this.min = min;
this.max = max;
this.style = style;
this.colorSet = colorSet;
}
protected final HColor closedBackgroundColor() {
return style.value(PName.BackGroundColor).asColor(colorSet);
}
protected final HColor closedFontColor() {
return style.value(PName.FontColor).asColor(colorSet);
}
public abstract double getTimeHeaderHeight();

View File

@ -41,8 +41,10 @@ import net.sourceforge.plantuml.project.LoadPlanable;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public abstract class TimeHeaderCalendar extends TimeHeader {
@ -51,8 +53,8 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
protected final Map<DayOfWeek, HColor> colorDaysOfWeek;
public TimeHeaderCalendar(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays,
Map<DayOfWeek, HColor> colorDaysOfWeek, TimeScale timeScale) {
super(min, max, timeScale);
Map<DayOfWeek, HColor> colorDaysOfWeek, TimeScale timeScale, Style style, HColorSet colorSet) {
super(min, max, timeScale, style, colorSet);
this.defaultPlan = defaultPlan;
this.colorDays = colorDays;
this.colorDaysOfWeek = colorDaysOfWeek;
@ -89,7 +91,7 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
back = backDoW;
}
if (back == null && defaultPlan.getLoadAt(wink) == 0) {
back = veryLightGray;
back = closedBackgroundColor();
}
if (back == null) {
if (pending != null)

View File

@ -43,10 +43,12 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleDaily;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderDaily extends TimeHeaderCalendar {
@ -63,8 +65,10 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
private final Map<Day, String> nameDays;
public TimeHeaderDaily(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays,
Map<DayOfWeek, HColor> colorDaysOfWeek, Map<Day, String> nameDays, Day printStart, Day printEnd) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleDaily(calendar, printStart));
Map<DayOfWeek, HColor> colorDaysOfWeek, Map<Day, String> nameDays, Day printStart, Day printEnd,
Style style, HColorSet colorSet) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleDaily(calendar, printStart),
style, colorSet);
this.nameDays = nameDays;
}
@ -111,7 +115,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
private HColor getTextBackColor(Day wink) {
if (defaultPlan.getLoadAt(wink) <= 0) {
return lightGray;
return closedFontColor();
}
return HColorUtils.BLACK;
}

View File

@ -43,10 +43,12 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderMonthly extends TimeHeaderCalendar {
@ -60,9 +62,9 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
}
public TimeHeaderMonthly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays,
Map<DayOfWeek, HColor> colorDaysOfWeek) {
Map<DayOfWeek, HColor> colorDaysOfWeek, Style style, HColorSet colorSet) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale));
new TimeScaleCompressed(calendar, scale), style, colorSet);
}
@Override

View File

@ -43,10 +43,12 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderQuarterly extends TimeHeaderCalendar {
@ -59,10 +61,10 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
return 16 + 13 - 1;
}
public TimeHeaderQuarterly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays,
Map<DayOfWeek, HColor> colorDaysOfWeek) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale));
public TimeHeaderQuarterly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, Style style, HColorSet colorSet) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale),
style, colorSet);
}
@Override
@ -126,9 +128,9 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
}
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12);
}
private String quarter(Day day) {
return "Q" + (( day.month().ordinal() + 3 ) / 3);
return "Q" + ((day.month().ordinal() + 3) / 3);
}
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {

View File

@ -42,9 +42,11 @@ import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.project.timescale.TimeScaleWink;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderSimple extends TimeHeader {
@ -66,8 +68,8 @@ public class TimeHeaderSimple extends TimeHeader {
return 0;
}
public TimeHeaderSimple(Day min, Day max) {
super(min, max, new TimeScaleWink());
public TimeHeaderSimple(Day min, Day max, Style style, HColorSet colorSet) {
super(min, max, new TimeScaleWink(), style, colorSet);
}
private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {

View File

@ -44,10 +44,12 @@ import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderWeekly extends TimeHeaderCalendar {
@ -63,8 +65,10 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
}
public TimeHeaderWeekly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, WeekNumberStrategy weekNumberStrategy) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale));
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, WeekNumberStrategy weekNumberStrategy,
Style style, HColorSet colorSet) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale),
style, colorSet);
this.weekNumberStrategy = weekNumberStrategy;
}

View File

@ -43,10 +43,12 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderYearly extends TimeHeaderCalendar {
@ -60,8 +62,9 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
}
public TimeHeaderYearly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale));
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, Style style, HColorSet colorSet) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale),
style, colorSet);
}
@Override

View File

@ -54,6 +54,7 @@ public enum SName {
class_, //
clickable, //
cloud, //
closed, //
collection, //
collections, //
component, //

View File

@ -53,8 +53,8 @@ import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.Bibliotekon;
import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UStroke;

View File

@ -71,8 +71,8 @@ import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.svek.SvekLine;
import net.sourceforge.plantuml.svek.SvekNode;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGraphicStencil;

View File

@ -37,13 +37,9 @@ package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineConfigurable;
import net.sourceforge.plantuml.SkinParamUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.IEntity;
@ -52,24 +48,16 @@ import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.ugraphic.Shadowable;
import net.sourceforge.plantuml.ugraphic.UEllipse;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UGroupType;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class EntityImageState extends AbstractEntityImage {
public class EntityImageState extends EntityImageStateCommon {
final private TextBlock desc;
final private TextBlock fields;
final private Url url;
final private static int MIN_WIDTH = 50;
final private static int MIN_HEIGHT = 50;
@ -81,25 +69,13 @@ public class EntityImageState extends AbstractEntityImage {
final static private double smallMarginX = 7;
final static private double smallMarginY = 4;
final private LineConfigurable lineConfig;
public EntityImageState(IEntity entity, ISkinParam skinParam) {
super(entity, skinParam);
this.lineConfig = entity;
final Stereotype stereotype = entity.getStereotype();
this.withSymbol = stereotype != null && stereotype.isWithOOSymbol();
this.desc = entity.getDisplay().create8(new FontConfiguration(getSkinParam(), FontParam.STATE, stereotype),
HorizontalAlignment.CENTER, skinParam, CreoleMode.FULL, skinParam.wrapWidth());
// Display list = Display.empty();
// for (Member att : entity.getBodier().getFieldsToDisplay()) {
// list = list.addAll(Display.getWithNewlines(att.getDisplay(true)));
// }
final Display list = Display.create(entity.getBodier().getRawBody());
this.url = entity.getUrl99();
this.fields = list.create8(new FontConfiguration(getSkinParam(), FontParam.STATE_ATTRIBUTE, stereotype),
HorizontalAlignment.LEFT, skinParam, CreoleMode.FULL, skinParam.wrapWidth());
@ -125,28 +101,11 @@ public class EntityImageState extends AbstractEntityImage {
final Dimension2D dimTotal = calculateDimension(stringBounder);
final Dimension2D dimDesc = desc.calculateDimension(stringBounder);
final double widthTotal = dimTotal.getWidth();
final double heightTotal = dimTotal.getHeight();
final Shadowable rect = new URectangle(widthTotal, heightTotal).rounded(CORNER);
if (getSkinParam().shadowing(getEntity().getStereotype())) {
rect.setDeltaShadow(4);
}
HColor classBorder = lineConfig.getColors(getSkinParam()).getColor(ColorType.LINE);
if (classBorder == null) {
classBorder = SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.stateBorder);
}
ug = ug.apply(getStroke()).apply(classBorder);
HColor backcolor = getEntity().getColors(getSkinParam()).getColor(ColorType.BACK);
if (backcolor == null) {
backcolor = SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.stateBackground);
}
ug = ug.apply(backcolor.bg());
ug.draw(rect);
ug = applyColor(ug);
ug.draw(getShape(dimTotal));
final double yLine = MARGIN + dimDesc.getHeight() + MARGIN_LINE;
ug.apply(UTranslate.dy(yLine)).draw(ULine.hline(widthTotal));
ug.apply(UTranslate.dy(yLine)).draw(ULine.hline(dimTotal.getWidth()));
ug = ug.apply(new UStroke());
@ -156,7 +115,7 @@ public class EntityImageState extends AbstractEntityImage {
drawSymbol(ug, xSymbol, ySymbol);
}
final double xDesc = (widthTotal - dimDesc.getWidth()) / 2;
final double xDesc = (dimTotal.getWidth() - dimDesc.getWidth()) / 2;
final double yDesc = MARGIN;
desc.drawU(ug.apply(new UTranslate(xDesc, yDesc)));
@ -170,14 +129,6 @@ public class EntityImageState extends AbstractEntityImage {
ug.closeGroup();
}
private UStroke getStroke() {
UStroke stroke = lineConfig.getColors(getSkinParam()).getSpecificLineStroke();
if (stroke == null) {
stroke = new UStroke(1.5);
}
return stroke;
}
public static void drawSymbol(UGraphic ug, double xSymbol, double ySymbol) {
xSymbol -= 4 * smallRadius + smallLine + smallMarginX;
ySymbol -= 2 * smallRadius + smallMarginY;
@ -187,8 +138,4 @@ public class EntityImageState extends AbstractEntityImage {
ug.apply(new UTranslate(xSymbol + 2 * smallRadius, ySymbol + smallLine)).draw(ULine.hline(smallLine));
}
public ShapeType getShapeType() {
return ShapeType.ROUND_RECTANGLE;
}
}

View File

@ -63,22 +63,15 @@ import net.sourceforge.plantuml.ugraphic.color.HColor;
public class EntityImageState2 extends AbstractEntityImage {
final private Url url;
final private LineConfigurable lineConfig;
// final private LineConfigurable lineConfig;
private final TextBlock asSmall;
public EntityImageState2(ILeaf entity, ISkinParam skinParam) {
super(entity, skinParam);
this.lineConfig = entity;
// this.lineConfig = entity;
final Stereotype stereotype = entity.getStereotype();
// Display list = Display.empty();
// for (Member att : entity.getBodier().getFieldsToDisplay()) {
// list = list.addAll(Display.getWithNewlines(att.getDisplay(true)));
// }
// final Display list = Display.create(entity.getBodier().getRawBody());
final USymbol symbol = USymbol.FRAME;
HColor backcolor = getEntity().getColors(getSkinParam()).getColor(ColorType.BACK);

View File

@ -0,0 +1,115 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineConfigurable;
import net.sourceforge.plantuml.SkinParamUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.IEntity;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public abstract class EntityImageStateCommon extends AbstractEntityImage {
final protected TextBlock desc;
final protected Url url;
final protected LineConfigurable lineConfig;
public EntityImageStateCommon(IEntity entity, ISkinParam skinParam) {
super(entity, skinParam);
this.lineConfig = entity;
final Stereotype stereotype = entity.getStereotype();
this.desc = entity.getDisplay().create8(new FontConfiguration(getSkinParam(), FontParam.STATE, stereotype),
HorizontalAlignment.CENTER, skinParam, CreoleMode.FULL, skinParam.wrapWidth());
this.url = entity.getUrl99();
}
final protected UStroke getStroke() {
UStroke stroke = lineConfig.getColors(getSkinParam()).getSpecificLineStroke();
if (stroke == null) {
stroke = new UStroke(1.5);
}
return stroke;
}
final public ShapeType getShapeType() {
return ShapeType.ROUND_RECTANGLE;
}
final protected URectangle getShape(final Dimension2D dimTotal) {
final URectangle rect = new URectangle(dimTotal).rounded(CORNER);
if (getSkinParam().shadowing(getEntity().getStereotype())) {
rect.setDeltaShadow(4);
}
return rect;
}
final protected UGraphic applyColor(UGraphic ug) {
HColor classBorder = lineConfig.getColors(getSkinParam()).getColor(ColorType.LINE);
if (classBorder == null) {
classBorder = SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.stateBorder);
}
ug = ug.apply(getStroke()).apply(classBorder);
HColor backcolor = getEntity().getColors(getSkinParam()).getColor(ColorType.BACK);
if (backcolor == null) {
backcolor = SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.stateBackground);
}
ug = ug.apply(backcolor.bg());
return ug;
}
}

View File

@ -37,51 +37,20 @@ package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.SkinParamUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.creole.CreoleMode;
import net.sourceforge.plantuml.cucadiagram.IEntity;
import net.sourceforge.plantuml.cucadiagram.Stereotype;
import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.color.ColorType;
import net.sourceforge.plantuml.svek.AbstractEntityImage;
import net.sourceforge.plantuml.svek.ShapeType;
import net.sourceforge.plantuml.ugraphic.Shadowable;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class EntityImageStateEmptyDescription extends AbstractEntityImage {
final private TextBlock desc;
final private Url url;
public class EntityImageStateEmptyDescription extends EntityImageStateCommon {
final private static int MIN_WIDTH = 50;
final private static int MIN_HEIGHT = 40;
public EntityImageStateEmptyDescription(IEntity entity, ISkinParam skinParam) {
super(entity, skinParam);
final Stereotype stereotype = entity.getStereotype();
this.desc = entity.getDisplay().create8(new FontConfiguration(getSkinParam(), FontParam.STATE, stereotype),
HorizontalAlignment.CENTER, skinParam, CreoleMode.FULL, skinParam.wrapWidth());
// Display list = Display.empty();
// for (Member att : entity.getBodier().getFieldsToDisplay()) {
// list = list.addAll(Display.getWithNewlines(att.getDisplay(true)));
// }
// final Display list = Display.create(entity.getBodier().getRawBody());
this.url = entity.getUrl99();
}
@ -99,23 +68,11 @@ public class EntityImageStateEmptyDescription extends AbstractEntityImage {
final Dimension2D dimTotal = calculateDimension(stringBounder);
final Dimension2D dimDesc = desc.calculateDimension(stringBounder);
final double widthTotal = dimTotal.getWidth();
final double heightTotal = dimTotal.getHeight();
final Shadowable rect = new URectangle(widthTotal, heightTotal).rounded(CORNER);
if (getSkinParam().shadowing(getEntity().getStereotype())) {
rect.setDeltaShadow(4);
}
ug = applyColor(ug);
ug.draw(getShape(dimTotal));
ug = ug.apply(new UStroke(1.5))
.apply(SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.stateBorder));
HColor backcolor = getEntity().getColors(getSkinParam()).getColor(ColorType.BACK);
if (backcolor == null) {
backcolor = SkinParamUtils.getColor(getSkinParam(), getStereo(), ColorParam.stateBackground);
}
ug = ug.apply(backcolor.bg());
ug.draw(rect);
final double xDesc = (widthTotal - dimDesc.getWidth()) / 2;
final double yDesc = (heightTotal - dimDesc.getHeight()) / 2;
final double xDesc = (dimTotal.getWidth() - dimDesc.getWidth()) / 2;
final double yDesc = (dimTotal.getHeight() - dimDesc.getHeight()) / 2;
desc.drawU(ug.apply(new UTranslate(xDesc, yDesc)));
if (url != null) {
@ -123,8 +80,4 @@ public class EntityImageStateEmptyDescription extends AbstractEntityImage {
}
}
public ShapeType getShapeType() {
return ShapeType.ROUND_RECTANGLE;
}
}

View File

@ -34,6 +34,8 @@
*/
package net.sourceforge.plantuml.version;
import static net.sourceforge.plantuml.graphic.GraphicPosition.BACKGROUND_CORNER_BOTTOM_RIGHT;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
@ -47,7 +49,7 @@ import net.sourceforge.plantuml.PlainStringsDiagram;
import net.sourceforge.plantuml.Run;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
import net.sourceforge.plantuml.dedication.Dedication;
import net.sourceforge.plantuml.dedication.PSystemDedication;
import net.sourceforge.plantuml.preproc.ImportedFiles;
import net.sourceforge.plantuml.preproc.Stdlib;
import net.sourceforge.plantuml.preproc2.PreprocessorUtils;
@ -57,8 +59,6 @@ import net.sourceforge.plantuml.security.SecurityProfile;
import net.sourceforge.plantuml.security.SecurityUtils;
import net.sourceforge.plantuml.svek.GraphvizCrash;
import static net.sourceforge.plantuml.graphic.GraphicPosition.BACKGROUND_CORNER_BOTTOM_RIGHT;
public class PSystemVersion extends PlainStringsDiagram {
PSystemVersion(boolean withImage, List<String> args) {
@ -126,7 +126,7 @@ public class PSystemVersion extends PlainStringsDiagram {
private static BufferedImage getImageWebp(final String name) {
try {
final InputStream is = PSystemVersion.class.getResourceAsStream(name);
final BufferedImage image = Dedication.getBufferedImage(is);
final BufferedImage image = PSystemDedication.getBufferedImage(is);
is.close();
return image;
} catch (IOException e) {

View File

@ -44,7 +44,7 @@ public class Version {
private static final int MAJOR_SEPARATOR = 1000000;
public static int version() {
return 1202104;
return 1202105;
}
public static int versionPatched() {
@ -80,7 +80,7 @@ public class Version {
}
public static int beta() {
final int beta = 5;
final int beta = 0;
return beta;
}
@ -93,7 +93,7 @@ public class Version {
}
public static long compileTime() {
return 1617526179012L;
return 1619349628741L;
}
public static String compileTimeString() {

View File

@ -1,3 +0,0 @@
.elem {cursor: pointer;}
.elem, .link {opacity: 0.3;}
.elem.selected, .link.selected {opacity: 1;}

View File

@ -1,110 +0,0 @@
function addItemToMapOfLists(mapOfLists, name, item) {
// mapOfLists = {
// 'key1': [item1, item2, ...],
// 'key2': [item3, item4, ...],
// }
if (mapOfLists[name].length > 0) {
if (!mapOfLists[name].includes(item)) {
mapOfLists[name].push(item);
}
} else {
mapOfLists[name] = [item];
}
}
function main() {
let elems = Array.from(document.getElementsByClassName('elem'));
let links = Array.from(document.getElementsByClassName('link'));
let elemsMap = {};
let linkedElems = {};
let linkedLinks = {};
elems.forEach(elem => {
let name = elem.classList[1];
elemsMap[name] = elem;
linkedElems[name] = [];
linkedLinks[name] = [];
});
links.forEach(link => {
let name1 = link.classList[1];
let name2 = link.classList[2];
if (elemsMap[name1]) {
if (elemsMap[name2]) {
let elem1 = elemsMap[name1];
let elem2 = elemsMap[name2];
addItemToMapOfLists(linkedElems, name1, elem2);
addItemToMapOfLists(linkedElems, name2, elem1);
addItemToMapOfLists(linkedLinks, name1, link);
addItemToMapOfLists(linkedLinks, name2, link);
}
}
});
let selectedElems = [];
let selectedLinks = [];
let selectedElemName = null;
function clearSelected() {
selectedElems.forEach(item => {
item.classList.remove('selected');
});
selectedElems = [];
selectedLinks.forEach(item => {
item.classList.remove('selected');
});
selectedLinks = [];
}
function selectAll() {
selectedElemName = null;
selectedElems = Array.from(elems);
selectedElems.forEach(item => {
item.classList.add('selected');
});
selectedLinks = Array.from(links);
selectedLinks.forEach(item => {
item.classList.add('selected');
});
}
function selectElem(elemName) {
if (elemName === selectedElemName) {
selectAll();
} else {
clearSelected();
selectedElemName = elemName;
elemsMap[elemName].classList.add('selected');
selectedElems.push(elemsMap[elemName]);
linkedElems[elemName].forEach(linkedElem => {
selectedElems.push(linkedElem);
linkedElem.classList.add('selected');
});
linkedLinks[elemName].forEach(linkedLink => {
selectedLinks.push(linkedLink);
linkedLink.classList.add('selected');
});
}
}
Object.keys(elemsMap).forEach(name => {
elemsMap[name].onclick = () => { selectElem(name); };
});
selectAll();
}
document.addEventListener('DOMContentLoaded', (event) => {
main();
});