Pull request #449: RED-4824

Merge in RED/redaction-service from RED-4824 to master

* commit '1d39c150c7e9084ae6a3833149ad66a4f31da774':
  RED-4824: Corrected code style by removing parameter assignment
  RED-4824: Replaced type of the text dir with an enum that only accepts values that can be handled by our code
  RED-4824: Recreated log files to include changes in rectangle calculation
  RED-4824: Removed obsolete logging statement
  RED-4824: Finalized affine transformation by correcting the center of the rotation according to the text direction
  RED-4824: WIP: Transformed rectangle calculation from a if-else chain to an affine transformation
  RED-4824: Added test with a simple pdf that contains all combinations for rotation and text direction
  RED-4824: Cleaned up code to make method more readable
  RED-4824: Created base test for text-position rectangle creation
This commit is contained in:
Viktor Seifert 2022-08-11 11:09:51 +02:00
commit 85c44374d9
148 changed files with 474 additions and 63271 deletions

View File

@ -0,0 +1,51 @@
package com.iqser.red.service.redaction.v1.server.parsing.model;
import java.util.Objects;
import lombok.Getter;
@Getter
public enum TextDirection {
ZERO(0f),
QUARTER_CIRCLE(90f),
HALF_CIRCLE(180f),
THREE_QUARTER_CIRCLE(270f);
public static final String VALUE_STRING_SUFFIX = "°";
private final float degrees;
private final float radians;
TextDirection(float degreeValue) {
degrees = degreeValue;
radians = (float) Math.toRadians(degreeValue);
}
@Override
public String toString() {
return degrees + VALUE_STRING_SUFFIX;
}
public static TextDirection fromDegrees(float degrees) {
for (var dir : TextDirection.values()) {
if (degrees == dir.degrees) {
return dir;
}
}
throw new IllegalArgumentException(String.format("A value of %f is not supported by TextDirection", degrees));
}
public static TextDirection fromString(String degreesAsString) {
Objects.requireNonNull(degreesAsString, "Cannot construct a text direction from a null value");
String value = degreesAsString.strip();
if (degreesAsString.endsWith(VALUE_STRING_SUFFIX)) {
value = degreesAsString.replace(VALUE_STRING_SUFFIX + "$", "");
}
return fromDegrees(Float.parseFloat(value));
}
}

View File

@ -1,5 +1,7 @@
package com.iqser.red.service.redaction.v1.server.parsing.model;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@ -17,6 +19,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ -28,10 +31,11 @@ import lombok.extern.slf4j.Slf4j;
@JsonIgnoreProperties({"empty"})
public class TextPositionSequence implements CharSequence {
public static final int HEIGHT_PADDING = 2;
private int page;
private List<RedTextPosition> textPositions = new ArrayList<>();
private float dir;
private TextDirection dir;
private int rotation;
private float pageHeight;
private float pageWidth;
@ -57,7 +61,7 @@ public class TextPositionSequence implements CharSequence {
this.textPositions = textPositions.stream().map(RedTextPosition::fromTextPosition).collect(Collectors.toList());
this.page = page;
this.dir = textPositions.get(0).getDir();
this.dir = TextDirection.fromDegrees(textPositions.get(0).getDir());
this.rotation = textPositions.get(0).getRotation();
this.pageHeight = textPositions.get(0).getPageHeight();
this.pageWidth = textPositions.get(0).getPageWidth();
@ -135,7 +139,7 @@ public class TextPositionSequence implements CharSequence {
this.textPositions.add(RedTextPosition.fromTextPosition(textPosition));
this.dir = textPositions.get(0).getDir();
this.dir = TextDirection.fromDegrees(textPositions.get(0).getDir());
this.rotation = textPositions.get(0).getRotation();
this.pageHeight = textPositions.get(0).getPageHeight();
this.pageWidth = textPositions.get(0).getPageWidth();
@ -162,8 +166,7 @@ public class TextPositionSequence implements CharSequence {
if (rotation == 90) {
return textPositions.get(0).getYDirAdj();
} else {
return textPositions.get(textPositions.size() - 1)
.getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + 1;
return textPositions.get(textPositions.size() - 1).getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + HEIGHT_PADDING;
}
}
@ -193,7 +196,7 @@ public class TextPositionSequence implements CharSequence {
public float getY2() {
if (rotation == 90) {
return textPositions.get(textPositions.size() - 1).getXDirAdj() + getTextHeight() - 2;
return textPositions.get(textPositions.size() - 1).getXDirAdj() + getTextHeight() - HEIGHT_PADDING;
} else {
return pageHeight - textPositions.get(0).getYDirAdj() + getTextHeight();
}
@ -204,7 +207,7 @@ public class TextPositionSequence implements CharSequence {
@JsonAttribute(ignore = true)
public float getTextHeight() {
return textPositions.get(0).getHeightDir() + 2;
return textPositions.get(0).getHeightDir() + HEIGHT_PADDING;
}
@ -269,148 +272,39 @@ public class TextPositionSequence implements CharSequence {
@JsonIgnore
@JsonAttribute(ignore = true)
@SneakyThrows
public Rectangle getRectangle() {
log.debug("Page: '{}', Word: '{}', Rotation: '{}', textRotation {}", page, toString(), rotation, dir);
log.debug("Page: '{}', Word: '{}', Rotation: '{}', textRotation {}", page, this, rotation, dir);
float height = getTextHeight();
float textHeight = getTextHeight();
float posXInit = getX1();
float posXEnd;
float posYInit;
float posYEnd;
RedTextPosition firstTextPos = textPositions.get(0);
RedTextPosition lastTextPos = textPositions.get(textPositions.size() - 1);
if (rotation == 0 && dir == 90f) {
posYInit = getX1();
posYEnd = getX2() + textPositions.get(0).getWidthDirAdj() - textPositions.get(textPositions.size() - 1)
.getWidthDirAdj() - 3;
posXInit = textPositions.get(0).getYDirAdj() + 2;
posXEnd = textPositions.get(textPositions.size() - 1).getYDirAdj() - height;
} else if (rotation == 0 && dir == 180f) {
posXInit = pageWidth - getX1() + 1;
posXEnd = pageWidth - getX2() + textPositions.get(0)
.getWidthDirAdj() - textPositions.get(textPositions.size() - 1).getWidthDirAdj() - 3;
posYInit = textPositions.get(0).getYDirAdj() - height + 2;
posYEnd = textPositions.get(textPositions.size() - 1).getYDirAdj() - height + 2;
} else if (rotation == 0 && dir == 270f) {
posYInit = pageHeight - getX1();
posYEnd = pageHeight - getX2() - textPositions.get(0)
.getWidthDirAdj() - textPositions.get(textPositions.size() - 1).getWidthDirAdj() - 3;
posXInit = pageWidth - textPositions.get(0).getYDirAdj() - 2;
posXEnd = pageWidth - textPositions.get(textPositions.size() - 1)
.getYDirAdj() + height;
} else if (rotation == 90 && dir == 0.0f) {
posXInit = textPositions.get(textPositions.size() - 1)
.getXDirAdj() + textPositions.get(textPositions.size() - 1).getHeightDir();
posXEnd = textPositions.get(0).getXDirAdj();
posYInit = pageHeight - textPositions.get(0).getYDirAdj() - 2;
posYEnd = pageHeight - textPositions.get(textPositions.size() - 1)
.getYDirAdj() + 2;
} else if (rotation == 90 && dir == 90.0f) {
posXEnd = textPositions.get(0).getYDirAdj() + 2;
posYInit = getY1();
posYEnd = textPositions.get(textPositions.size() - 1).getXDirAdj() - height + 4;
} else if (rotation == 90 && dir == 180.0f) {
posXInit = pageWidth - textPositions.get(textPositions.size() - 1)
.getXDirAdj() - 4;
posXEnd = pageWidth - textPositions.get(0).getXDirAdj();
posYInit = textPositions.get(0).getYDirAdj() - 2 - textPositions.get(textPositions.size() - 1)
.getHeightDir();
posYEnd = textPositions.get(textPositions.size() - 1)
.getYDirAdj() - textPositions.get(textPositions.size() - 1).getHeightDir();
} else if (rotation == 90 && dir == 270.0f) {
posXInit = pageWidth - getX1();
posXEnd = pageWidth - textPositions.get(0).getYDirAdj() - 2;
posYInit = pageHeight - getY1();
posYEnd = pageHeight - textPositions.get(textPositions.size() - 1)
.getXDirAdj() - height - 4;
} else if (rotation == 180 && dir == 0f) {
posXEnd = textPositions.get(textPositions.size() - 1)
.getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + 1;
posYInit = pageHeight - textPositions.get(0).getYDirAdj() - 2;
posYEnd = pageHeight - textPositions.get(textPositions.size() - 1)
.getYDirAdj() + 2;
} else if (rotation == 180 && dir == 90f) {
posYInit = getX1();
posYEnd = getX2() - 3;
posXInit = textPositions.get(0).getYDirAdj() + 2;
posXEnd = textPositions.get(textPositions.size() - 1).getYDirAdj() - height;
} else if (rotation == 180 && dir == 180f) {
posXInit = pageWidth - getX1() + 1;
posXEnd = pageWidth - getX2() + textPositions.get(0)
.getWidthDirAdj() - textPositions.get(textPositions.size() - 1).getWidthDirAdj() - 3;
posYInit = textPositions.get(0).getYDirAdj() - height + 2;
posYEnd = textPositions.get(textPositions.size() - 1).getYDirAdj() - height + 2;
} else if (rotation == 180 && dir == 270.0f) {
posYInit = pageHeight - getX1();
posYEnd = pageHeight - getX2() - textPositions.get(0)
.getWidthDirAdj() - textPositions.get(textPositions.size() - 1).getWidthDirAdj();
posXInit = pageWidth - textPositions.get(0).getYDirAdj() - 2;
posXEnd = pageWidth - textPositions.get(textPositions.size() - 1)
.getYDirAdj() + height;
} else if (rotation == 270 && dir == 0.0f) {
posYInit = pageHeight - textPositions.get(0).getYDirAdj() - 2;
posYEnd = posYInit + 1;
posXInit = textPositions.get(0).getXDirAdj();
posXEnd = textPositions.get(textPositions.size() - 1)
.getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + 0.1f;
} else if (rotation == 270 && dir == 90.0f) {
posYInit = getX1();
posYEnd = getX2() - height;
posXInit = textPositions.get(0).getYDirAdj() + 2;
posXEnd = textPositions.get(textPositions.size() - 1).getYDirAdj() - height;
} else if (rotation == 270 && dir == 180.0f) {
posXInit = pageWidth - getX1() + 1;
posXEnd = pageWidth - getX2() - 4;
posYInit = textPositions.get(0).getYDirAdj() - height + 2;
posYEnd = textPositions.get(textPositions.size() - 1).getYDirAdj() - height + 2;
} else if (rotation == 270 && dir == 270.0f) {
posYInit = pageHeight - getX1();
posYEnd = pageHeight - getX2() - height;
posXInit = pageWidth - textPositions.get(0).getYDirAdj() - 2;
posXEnd = pageWidth - textPositions.get(textPositions.size() - 1)
.getYDirAdj() + height;
Point2D bottomLeft = new Point2D.Double(firstTextPos.getXDirAdj(), firstTextPos.getYDirAdj() - HEIGHT_PADDING);
Point2D topRight = new Point2D.Double(lastTextPos.getXDirAdj() + lastTextPos.getWidthDirAdj(), lastTextPos.getYDirAdj() + textHeight + HEIGHT_PADDING);
AffineTransform transform = new AffineTransform();
if (dir == TextDirection.ZERO || dir == TextDirection.HALF_CIRCLE) {
transform.rotate(dir.getRadians(), pageWidth / 2f, pageHeight / 2f);
transform.translate(0f, pageHeight + textHeight);
transform.scale(1., -1.);
} else if (dir == TextDirection.QUARTER_CIRCLE) {
transform.rotate(dir.getRadians(), pageWidth / 2f, pageWidth / 2f);
transform.translate(0f, pageWidth + textHeight);
transform.scale(1., -1.);
} else {
// page rotation = 0 and text direction = 0
posXEnd = textPositions.get(textPositions.size() - 1)
.getXDirAdj() + textPositions.get(textPositions.size() - 1).getWidthDirAdj() + 1;
posYInit = pageHeight - textPositions.get(0).getYDirAdj() - 2;
posYEnd = pageHeight - textPositions.get(textPositions.size() - 1)
.getYDirAdj() + 2;
transform.rotate(dir.getRadians(), pageHeight / 2f, pageHeight / 2f);
transform.translate(0f, pageWidth + textHeight);
transform.scale(1., -1.);
}
var rectangle = new Rectangle(new Point(posXInit, posYInit), posXEnd - posXInit, posYEnd - posYInit + height, page);
log.debug("Rectangle: {}", rectangle);
return rectangle;
bottomLeft = transform.transform(bottomLeft, null);
topRight = transform.transform(topRight, null);
return new Rectangle( //
new Point((float) bottomLeft.getX(), (float) bottomLeft.getY()), (float) (topRight.getX() - bottomLeft.getX()), (float) (topRight.getY() - bottomLeft.getY()), page);
}
}

View File

@ -118,10 +118,6 @@ public class EntitySearchUtils {
public void markFalsePositives(Set<Entity> entities, Set<Entity> falsePositives) {
if (entities.size() == 2) {
log.info("asd");
}
List<Entity> wordsToRemove = new ArrayList<>();
for (Entity word : falsePositives) {
for (Entity inner : entities) {

View File

@ -41,6 +41,7 @@ import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.mockito.stubbing.Answer;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@ -90,6 +91,7 @@ public class RedactionIntegrationTest {
private static final String DOSSIER_REDACTIONS = "dossier_redactions";
private static final String IMPORTED_REDACTION = "imported_redaction";
private static final String PII = "PII";
private static final String ROTATE_SIMPLE = "RotateSimple";
@Autowired
private RedactionController redactionController;
@ -217,25 +219,26 @@ public class RedactionIntegrationTest {
private void mockDictionaryCalls(Long version) {
when(dictionaryClient.getDictionaryForType(VERTEBRATE + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(VERTEBRATE, false));
when(dictionaryClient.getDictionaryForType(ADDRESS + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(ADDRESS, false));
when(dictionaryClient.getDictionaryForType(AUTHOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(AUTHOR, false));
when(dictionaryClient.getDictionaryForType(SPONSOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(SPONSOR, false));
when(dictionaryClient.getDictionaryForType(NO_REDACTION_INDICATOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(NO_REDACTION_INDICATOR, false));
when(dictionaryClient.getDictionaryForType(REDACTION_INDICATOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(REDACTION_INDICATOR, false));
when(dictionaryClient.getDictionaryForType(HINT_ONLY + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(HINT_ONLY, false));
when(dictionaryClient.getDictionaryForType(MUST_REDACT + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(MUST_REDACT, false));
when(dictionaryClient.getDictionaryForType(PUBLISHED_INFORMATION + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(PUBLISHED_INFORMATION, false));
when(dictionaryClient.getDictionaryForType(TEST_METHOD + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(TEST_METHOD, false));
when(dictionaryClient.getDictionaryForType(PII + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(PII, false));
when(dictionaryClient.getDictionaryForType(PURITY + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(PURITY, false));
when(dictionaryClient.getDictionaryForType(IMAGE + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(IMAGE, false));
when(dictionaryClient.getDictionaryForType(OCR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(OCR, false));
when(dictionaryClient.getDictionaryForType(LOGO + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(LOGO, false));
when(dictionaryClient.getDictionaryForType(SIGNATURE + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(SIGNATURE, false));
when(dictionaryClient.getDictionaryForType(FORMULA + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(FORMULA, false));
when(dictionaryClient.getDictionaryForType(DOSSIER_REDACTIONS + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(DOSSIER_REDACTIONS, true));
when(dictionaryClient.getDictionaryForType(IMPORTED_REDACTION + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).thenReturn(getDictionaryResponse(IMPORTED_REDACTION, true));
when(dictionaryClient.getDictionaryForType(VERTEBRATE + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(VERTEBRATE, false));
when(dictionaryClient.getDictionaryForType(ADDRESS + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(ADDRESS, false));
when(dictionaryClient.getDictionaryForType(AUTHOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(AUTHOR, false));
when(dictionaryClient.getDictionaryForType(SPONSOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(SPONSOR, false));
when(dictionaryClient.getDictionaryForType(NO_REDACTION_INDICATOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(NO_REDACTION_INDICATOR, false));
when(dictionaryClient.getDictionaryForType(REDACTION_INDICATOR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(REDACTION_INDICATOR, false));
when(dictionaryClient.getDictionaryForType(HINT_ONLY + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(HINT_ONLY, false));
when(dictionaryClient.getDictionaryForType(MUST_REDACT + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(MUST_REDACT, false));
when(dictionaryClient.getDictionaryForType(PUBLISHED_INFORMATION + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(PUBLISHED_INFORMATION, false));
when(dictionaryClient.getDictionaryForType(TEST_METHOD + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(TEST_METHOD, false));
when(dictionaryClient.getDictionaryForType(PII + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(PII, false));
when(dictionaryClient.getDictionaryForType(PURITY + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(PURITY, false));
when(dictionaryClient.getDictionaryForType(IMAGE + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(IMAGE, false));
when(dictionaryClient.getDictionaryForType(OCR + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(OCR, false));
when(dictionaryClient.getDictionaryForType(LOGO + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(LOGO, false));
when(dictionaryClient.getDictionaryForType(SIGNATURE + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(SIGNATURE, false));
when(dictionaryClient.getDictionaryForType(FORMULA + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(FORMULA, false));
when(dictionaryClient.getDictionaryForType(ROTATE_SIMPLE + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(ROTATE_SIMPLE, false));
when(dictionaryClient.getDictionaryForType(DOSSIER_REDACTIONS + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(DOSSIER_REDACTIONS, true));
when(dictionaryClient.getDictionaryForType(IMPORTED_REDACTION + ":" + TEST_DOSSIER_TEMPLATE_ID, version)).then((Answer<Type>) invocation -> getDictionaryResponse(IMPORTED_REDACTION, true));
}
@ -851,6 +854,33 @@ public class RedactionIntegrationTest {
System.out.println("numberOfPages: " + result.getNumberOfPages());
}
@Test
public void testRotationsSimple() throws IOException {
loadOnlyDictionaryForSimpleFile();
mockDictionaryCalls(null);
mockDictionaryCalls(0L);
System.out.println("testTableRedaction");
long start = System.currentTimeMillis();
AnalyzeRequest request = prepareStorage("files/new/RotateTestFileSimple.pdf");
analyzeService.analyzeDocumentStructure(new StructureAnalyzeRequest(request.getDossierId(), request.getFileId()));
AnalyzeResult result = analyzeService.analyze(request);
AnnotateResponse annotateResponse = annotationService.annotate(AnnotateRequest.builder()
.dossierId(TEST_DOSSIER_ID)
.fileId(TEST_FILE_ID)
.build());
try (FileOutputStream fileOutputStream = new FileOutputStream(OsUtils.getTemporaryDirectory() + "/AnnotatedSimple.pdf")) {
fileOutputStream.write(annotateResponse.getDocument());
}
long end = System.currentTimeMillis();
System.out.println("duration: " + (end - start));
System.out.println("numberOfPages: " + result.getNumberOfPages());
}
@Test
public void testFindDictionaryEntryInResizedEntryPosition() throws IOException {
@ -1474,6 +1504,15 @@ public class RedactionIntegrationTest {
}
private void loadOnlyDictionaryForSimpleFile() {
dictionary.clear();
dictionary.computeIfAbsent(ROTATE_SIMPLE, v -> new ArrayList<>())
.addAll(ResourceLoader.load("dictionaries/RotateTestFileSimple.txt")
.stream()
.map(this::cleanDictionaryEntry)
.collect(Collectors.toSet()));
}
private static String loadFromClassPath(String path) {
@ -1532,6 +1571,7 @@ public class RedactionIntegrationTest {
typeColorMap.put(FORMULA, "#ffe187");
typeColorMap.put(SIGNATURE, "#ffe187");
typeColorMap.put(IMPORTED_REDACTION, "#fcfbe6");
typeColorMap.put(ROTATE_SIMPLE, "#66ccff");
hintTypeMap.put(VERTEBRATE, true);
hintTypeMap.put(ADDRESS, false);
@ -1552,6 +1592,7 @@ public class RedactionIntegrationTest {
hintTypeMap.put(SIGNATURE, false);
hintTypeMap.put(DOSSIER_REDACTIONS, false);
hintTypeMap.put(IMPORTED_REDACTION, false);
hintTypeMap.put(ROTATE_SIMPLE, false);
caseInSensitiveMap.put(VERTEBRATE, true);
caseInSensitiveMap.put(ADDRESS, false);
@ -1572,6 +1613,7 @@ public class RedactionIntegrationTest {
caseInSensitiveMap.put(FORMULA, true);
caseInSensitiveMap.put(DOSSIER_REDACTIONS, false);
caseInSensitiveMap.put(IMPORTED_REDACTION, false);
caseInSensitiveMap.put(ROTATE_SIMPLE, true);
recommendationTypeMap.put(VERTEBRATE, false);
recommendationTypeMap.put(ADDRESS, false);
@ -1592,6 +1634,7 @@ public class RedactionIntegrationTest {
recommendationTypeMap.put(LOGO, false);
recommendationTypeMap.put(DOSSIER_REDACTIONS, false);
recommendationTypeMap.put(IMPORTED_REDACTION, false);
recommendationTypeMap.put(ROTATE_SIMPLE, false);
rankTypeMap.put(PURITY, 155);
rankTypeMap.put(PII, 150);
@ -1612,6 +1655,7 @@ public class RedactionIntegrationTest {
rankTypeMap.put(FORMULA, 26);
rankTypeMap.put(DOSSIER_REDACTIONS, 200);
rankTypeMap.put(IMPORTED_REDACTION, 200);
rankTypeMap.put(ROTATE_SIMPLE, 150);
colors.setSkippedColor("#cccccc");
colors.setRequestAddColor("#04b093");
@ -1661,7 +1705,6 @@ public class RedactionIntegrationTest {
.build();
}
private String cleanDictionaryEntry(String entry) {
return TextNormalizationUtilities.removeHyphenLineBreaks(entry).replaceAll("\\n", " ");
@ -1669,6 +1712,8 @@ public class RedactionIntegrationTest {
private List<DictionaryEntry> toDictionaryEntry(List<String> entries) {
if (entries == null)
entries = Collections.emptyList();
List<DictionaryEntry> dictionaryEntries = new ArrayList<>();
entries.forEach(entry -> {

View File

@ -0,0 +1,167 @@
package com.iqser.red.service.redaction.v1.server.parsing.model;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import java.io.IOException;
import java.io.InputStream;
import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.text.TextPosition;
import org.apache.pdfbox.util.Matrix;
import org.junit.jupiter.api.Test;
import lombok.SneakyThrows;
public class TextPositionSequenceTest {
public static final float UNROTAED_RECTANGLE_X_OFFSET = 0.f;
public static final float UNROTATED_RECTANGLE_Y_OFFSET = -2.f;
public static final float UNROTATED_RECTANGLE_WIDTH_OFFSET = 1.f;
public static final float UNROTATED_RECTANGLE_HEIGHT_OFFSET = 6.f;
@Test
@SneakyThrows
public void testSinglePosNoRotationRectangle() {
int page = 2;
var testSequence = new TextPositionSequence(page);
float endX = 4.f;
float endY = 5.f;
float maxHeight = 20.f;
var redTextPosition = createTextPosition(0, endX, endY, maxHeight);
testSequence.add(redTextPosition);
var rectangle = testSequence.getRectangle();
assertThat(rectangle.getPage()).isEqualTo(page);
assertThat(rectangle.getTopLeft().getX()).isEqualTo(UNROTAED_RECTANGLE_X_OFFSET);
assertThat(rectangle.getTopLeft().getY()).isEqualTo(UNROTATED_RECTANGLE_Y_OFFSET);
assertThat(rectangle.getWidth()).isEqualTo(endX + UNROTATED_RECTANGLE_WIDTH_OFFSET);
assertThat(rectangle.getHeight()).isEqualTo(maxHeight + UNROTATED_RECTANGLE_HEIGHT_OFFSET);
}
private TextPosition createTextPosition(int pageRotation, float endX, float endY, float maxHeight) throws IOException {
return new TextPosition(pageRotation, 100, 200, createIdentityMatrix(), endX, endY, maxHeight, 4, 2, "a", null, new DummyFont(), 14, 42);
}
private Matrix createIdentityMatrix() {
return new Matrix();
}
private static class DummyFont extends PDFont {
public DummyFont() throws IOException {
super(new COSDictionary());
}
@Override
protected float getStandard14Width(int i) {
throw new RuntimeException("not implemented");
}
@Override
protected byte[] encode(int i) {
throw new RuntimeException("not implemented");
}
@Override
public int readCode(InputStream inputStream) {
throw new RuntimeException("not implemented");
}
@Override
public boolean isVertical() {
throw new RuntimeException("not implemented");
}
@Override
public void addToSubset(int i) {
throw new RuntimeException("not implemented");
}
@Override
public void subset() {
throw new RuntimeException("not implemented");
}
@Override
public boolean willBeSubset() {
throw new RuntimeException("not implemented");
}
@Override
public String getName() {
return "DummyFont";
}
@Override
public BoundingBox getBoundingBox() {
throw new RuntimeException("not implemented");
}
@Override
public float getHeight(int i) {
throw new RuntimeException("not implemented");
}
@Override
public boolean hasExplicitWidth(int i) {
throw new RuntimeException("not implemented");
}
@Override
public float getWidthFromFont(int i) {
throw new RuntimeException("not implemented");
}
@Override
public boolean isEmbedded() {
throw new RuntimeException("not implemented");
}
@Override
public boolean isDamaged() {
throw new RuntimeException("not implemented");
}
}
}

View File

@ -1 +1 @@
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"12ac3d26ce82a77e469c64d56081662d","type":"CBI_author","value":"Micheletti S","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Table in: COPY OF THE APPLICATION FOR RENEWAL, MADE UNDER COMMISSION","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":214.8,"y":639.64},"width":55.039078,"height":11.52,"page":4}],"sectionNumber":3,"textBefore":"Report: Document F/02, ","textAfter":". (2014). Cyprodinil","comments":[],"startOffset":23,"endOffset":35,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398559.316208600}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false},{"id":"dd614353319e7c5a8cf8b3346dc12fac","type":"CBI_author","value":"Micheletti S","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"COPY OF THE APPLICATION FOR RENEWAL, MADE UNDER COMMISSION","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":306.84,"y":667.12},"width":60.71997,"height":12.0,"page":4}],"sectionNumber":5,"textBefore":"F report (","textAfter":"., 2014).","comments":[],"startOffset":247,"endOffset":259,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398559.316208600}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"12ac3d26ce82a77e469c64d56081662d","type":"CBI_author","value":"Micheletti S","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Table in: COPY OF THE APPLICATION FOR RENEWAL, MADE UNDER COMMISSION","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":214.8,"y":651.16003},"width":54.039078,"height":-11.520004,"page":4}],"sectionNumber":3,"textBefore":"Report: Document F/02, ","textAfter":". (2014). Cyprodinil","comments":[],"startOffset":23,"endOffset":35,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:30:48.6451565+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false},{"id":"dd614353319e7c5a8cf8b3346dc12fac","type":"CBI_author","value":"Micheletti S","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"COPY OF THE APPLICATION FOR RENEWAL, MADE UNDER COMMISSION","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":306.84,"y":679.12},"width":59.71997,"height":-12.0,"page":4}],"sectionNumber":5,"textBefore":"F report (","textAfter":"., 2014).","comments":[],"startOffset":247,"endOffset":259,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:30:48.6451565+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}

View File

@ -1 +1 @@
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"36a5e8909a18a5080dd423afb8efd7a7","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":159.0,"y":320.0},"width":10.208038,"height":-21.999977,"page":1}],"sectionNumber":3,"textBefore":"Product Metabolism and ","textAfter":" 1 of","comments":[],"startOffset":368,"endOffset":372,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398772.538085900}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false},{"id":"dca119c3aadd348bc43c0b700c0075c3","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":100.0,"y":81.0},"width":10.208031,"height":-22.0,"page":1}],"sectionNumber":3,"textBefore":"Pages RAM 465/02 ","textAfter":" 1 Tel:","comments":[],"startOffset":399,"endOffset":403,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398772.538085900}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false},{"id":"ef6e0f0ed413dbd7299d992d9a50840b","type":"CBI_author","value":"Crook","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":374.0,"y":389.0},"width":10.515198,"height":-27.02501,"page":1}],"sectionNumber":5,"textBefore":"Author : SJ ","textAfter":" Analytical Science","comments":[],"startOffset":12,"endOffset":17,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398772.538085900}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false},{"id":"0fac36714dd9d1c745565c6dfe06b9b7","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":514.14215,"y":47.94165},"width":24.39972,"height":11.591161,"page":2}],"sectionNumber":4,"textBefore":"RAM 465/02 ","textAfter":" 2 Summary","comments":[],"startOffset":11,"endOffset":15,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398772.538085900}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"36a5e8909a18a5080dd423afb8efd7a7","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":171.20801,"y":320.0},"width":-12.208008,"height":-20.99997,"page":1}],"sectionNumber":3,"textBefore":"Product Metabolism and ","textAfter":" 1 of","comments":[],"startOffset":368,"endOffset":372,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:35:37.8742785+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false},{"id":"dca119c3aadd348bc43c0b700c0075c3","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":112.20801,"y":81.0},"width":-12.208008,"height":-21.0,"page":1}],"sectionNumber":3,"textBefore":"Pages RAM 465/02 ","textAfter":" 1 Tel:","comments":[],"startOffset":399,"endOffset":403,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:35:37.8742785+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false},{"id":"ef6e0f0ed413dbd7299d992d9a50840b","type":"CBI_author","value":"Crook","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":386.5152,"y":389.0},"width":-12.515198,"height":-26.024994,"page":1}],"sectionNumber":5,"textBefore":"Author : SJ ","textAfter":" Analytical Science","comments":[],"startOffset":12,"endOffset":17,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:35:37.8742785+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false},{"id":"0fac36714dd9d1c745565c6dfe06b9b7","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":514.14215,"y":59.532837},"width":23.39972,"height":-11.591187,"page":2}],"sectionNumber":4,"textBefore":"RAM 465/02 ","textAfter":" 2 Summary","comments":[],"startOffset":11,"endOffset":15,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:35:37.8742785+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}

View File

@ -1 +1 @@
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"71770acab1fa63f46c026966890b5231","type":"vertebrate","value":"rabbit","reason":null,"matchedRule":0,"rectangle":false,"legalBasis":null,"imported":false,"redacted":false,"section":"","color":[1.0,0.52156866,0.96862745],"positions":[{"topLeft":{"x":77.73999,"y":537.62},"width":-11.043678,"height":36.630165,"page":1}],"sectionNumber":4,"textBefore":null,"textAfter":null,"comments":[],"startOffset":41,"endOffset":47,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398329.875800000}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":true,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"71770acab1fa63f46c026966890b5231","type":"vertebrate","value":"rabbit","reason":null,"matchedRule":0,"rectangle":false,"legalBasis":null,"imported":false,"redacted":false,"section":"","color":[1.0,0.52156866,0.96862745],"positions":[{"topLeft":{"x":64.69629,"y":537.62},"width":13.043678,"height":34.858643,"page":1}],"sectionNumber":4,"textBefore":null,"textAfter":null,"comments":[],"startOffset":41,"endOffset":47,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:32:41.4306318+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":true,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}

View File

@ -1 +1 @@
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"64eb5ff4ea1db8665fb6e57c5369b411","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Text in table","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":154.48782,"y":654.18},"width":9.992157,"height":19.882175,"page":1}],"sectionNumber":8,"textBefore":null,"textAfter":" 1 of","comments":[],"startOffset":54,"endOffset":58,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398731.072100800}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"64eb5ff4ea1db8665fb6e57c5369b411","type":"PII","value":"Page","reason":"Personal information found","matchedRule":19,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Text in table","color":[0.4,0.8,1.0],"positions":[{"topLeft":{"x":152.4878,"y":654.18},"width":11.992157,"height":20.888428,"page":1}],"sectionNumber":8,"textBefore":null,"textAfter":" 1 of","comments":[],"startOffset":54,"endOffset":58,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:34:38.324063+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}

View File

@ -1 +1 @@
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"9f6837120752b85c20e27d4cb199bd51","type":"CBI_author","value":"B. Foo","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":92.520004,"y":712.96},"width":31.589584,"height":12.231649,"page":1}],"sectionNumber":3,"textBefore":null,"textAfter":" F. Bar","comments":[],"startOffset":0,"endOffset":6,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398909.230209400}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false},{"id":"fb930b7f3acf65a74b0b59fee32cc6fa","type":"CBI_author","value":"F. Bar","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":125.92424,"y":712.96},"width":29.137009,"height":12.231649,"page":1}],"sectionNumber":3,"textBefore":"B. Foo ","textAfter":" Foo, B.","comments":[],"startOffset":7,"endOffset":13,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398909.230209400}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false},{"id":"435224747b87ed87b60ab363e6610fba","type":"CBI_author","value":"Foo","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":92.520004,"y":686.8},"width":18.338272,"height":12.231649,"page":1}],"sectionNumber":3,"textBefore":"Foo F. Bar ","textAfter":", B.","comments":[],"startOffset":14,"endOffset":17,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":1658398909.230209400}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"dossierDictionaryEntry":false,"recommendation":false,"hint":false,"dictionaryEntry":true,"falsePositive":false,"image":false,"localManualRedaction":false,"manuallyRemoved":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}
{"analysisVersion":1,"analysisNumber":0,"redactionLogEntry":[{"id":"9f6837120752b85c20e27d4cb199bd51","type":"CBI_author","value":"B. Foo","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":92.520004,"y":725.19165},"width":30.589584,"height":-12.231651,"page":1}],"sectionNumber":3,"textBefore":null,"textAfter":" F. Bar","comments":[],"startOffset":0,"endOffset":6,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:33:22.8488937+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false},{"id":"fb930b7f3acf65a74b0b59fee32cc6fa","type":"CBI_author","value":"F. Bar","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":125.92424,"y":725.19165},"width":28.137009,"height":-12.231651,"page":1}],"sectionNumber":3,"textBefore":"B. Foo ","textAfter":" Foo, B.","comments":[],"startOffset":7,"endOffset":13,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:33:22.8488937+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false},{"id":"435224747b87ed87b60ab363e6610fba","type":"CBI_author","value":"Foo","reason":"Author found","matchedRule":1,"rectangle":false,"legalBasis":"Article 39(e)(3) of Regulation (EC) No 178/2002","imported":false,"redacted":true,"section":"Header","color":[1.0,0.88235295,0.5294118],"positions":[{"topLeft":{"x":92.520004,"y":699.0316},"width":17.338272,"height":-12.231651,"page":1}],"sectionNumber":3,"textBefore":"Foo F. Bar ","textAfter":", B.","comments":[],"startOffset":14,"endOffset":17,"imageHasTransparency":false,"excluded":false,"sourceId":null,"changes":[{"analysisNumber":0,"type":"ADDED","dateTime":"2022-08-09T16:33:22.8488937+02:00"}],"manualChanges":[],"engines":["DICTIONARY"],"reference":[],"importedRedactionIntersections":[],"recommendation":false,"hint":false,"manuallyRemoved":false,"dictionaryEntry":true,"image":false,"falsePositive":false,"dossierDictionaryEntry":false,"localManualRedaction":false}],"legalBasis":[],"dictionaryVersion":0,"dossierDictionaryVersion":0,"rulesVersion":0,"legalBasisVersion":0}

Some files were not shown because too many files have changed in this diff Show More