From 9d4a8feb2b5253547d4440606d671fcdbce4b7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 22 Oct 2023 10:25:50 +0200 Subject: [PATCH] Added Context menu items to create new tags (shape, sprite, image, movie, sound, binaryData) from files and using font embed dialog for fonts --- CHANGELOG.md | 2 + .../flash/importers/ImageImporter.java | 23 ++- .../flash/importers/MovieImporter.java | 58 ++++++- .../decompiler/flash/gui/FontEmbedDialog.java | 42 ++++- .../jpexs/decompiler/flash/gui/FontFace.java | 8 + .../jpexs/decompiler/flash/gui/FontPanel.java | 68 +++++---- .../jpexs/decompiler/flash/gui/MainPanel.java | 42 +++-- .../decompiler/flash/gui/PreviewPanel.java | 8 +- .../flash/gui/graphics/importbinarydata16.png | Bin 0 -> 5904 bytes .../flash/gui/graphics/importbinarydata32.png | Bin 0 -> 8190 bytes .../flash/gui/graphics/importfont16.png | Bin 0 -> 6021 bytes .../flash/gui/graphics/importfont32.png | Bin 0 -> 8568 bytes .../gui/locales/FontEmbedDialog.properties | 5 + .../gui/locales/FontEmbedDialog_cs.properties | 5 + .../flash/gui/locales/MainFrame.properties | 10 +- .../flash/gui/locales/MainFrame_cs.properties | 10 +- .../flash/gui/tagtree/TagTreeContextMenu.java | 144 +++++++++++++++--- 17 files changed, 359 insertions(+), 66 deletions(-) create mode 100644 src/com/jpexs/decompiler/flash/gui/graphics/importbinarydata16.png create mode 100644 src/com/jpexs/decompiler/flash/gui/graphics/importbinarydata32.png create mode 100644 src/com/jpexs/decompiler/flash/gui/graphics/importfont16.png create mode 100644 src/com/jpexs/decompiler/flash/gui/graphics/importfont32.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dfa6d2fa..3b55edd51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - ActionScript Debugger - Call stack frames switching - view variables around call stack - ActionScript Debugger - Highlight lines of callstack - [#2105] GFX - Basic tag info +- Context menu items to create new tags (shape, sprite, image, movie, sound, binaryData) from files + and using font embed dialog for fonts ### Fixed - [#1306], [#1768] Maximizing window on other than main monitor diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java index 596e60019..ddc6dbc3b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ImageImporter.java @@ -53,8 +53,16 @@ public class ImageImporter extends TagImporter { return importImage(it, newData, 0); } + /** + * + * @param it + * @param newData + * @param tagType 0 = can change for defineBits, -1 = detect based on data + * @return + * @throws IOException + */ public Tag importImage(ImageTag it, byte[] newData, int tagType) throws IOException { - if (newData[0] == 'B' && newData[1] == 'M') { + if (newData.length >= 2 && newData[0] == 'B' && newData[1] == 'M') { BufferedImage b = ImageHelper.read(newData); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageHelper.write(b, ImageFormat.PNG, baos); @@ -69,6 +77,18 @@ public class ImageImporter extends TagImporter { tagType = it.getId(); } } + if (tagType == -1) { + if (newData.length >= 4 + && newData[0] == (byte) 0xff + && newData[1] == (byte) 0xd8 + && newData[2] == (byte) 0xff + && newData[3] == (byte) 0xe0 + ) { + tagType = DefineBitsJPEG2Tag.ID; + } else { + tagType = DefineBitsLosslessTag.ID; + } + } if (it.getId() == tagType) { it.setImage(newData); @@ -108,6 +128,7 @@ public class ImageImporter extends TagImporter { imageTag.setModified(true); it.getTimelined().replaceTag(it, imageTag); + imageTag.setTimelined(it.getTimelined()); swf.updateCharacters(); swf.resetTimelines(swf); return imageTag; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java index 31181b1e0..77dcd6384 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/MovieImporter.java @@ -261,9 +261,13 @@ public class MovieImporter { if (timelined != null) { timelined.resetTimeline(); } + if (timelined == null) { + timelined = movie.getTimelined(); + } int startFrame = 0; int placeDepth = -1; + int maxPlaceDepth = 0; if (timelined != null) { for (Tag t : timelined.getTags()) { if (t instanceof ShowFrameTag) { @@ -275,13 +279,47 @@ public class MovieImporter { placeDepth = pt.getDepth(); break; } + if (pt.getDepth() > -1) { + if (pt.getDepth() > maxPlaceDepth) { + maxPlaceDepth = pt.getDepth(); + } + } } } } + if (placeDepth == -1) { + placeDepth = maxPlaceDepth + 1; + startFrame = 0; + } int numTimelineFrames = timelined == null ? 0 : timelined.getFrameCount(); int importLastFrame = -1; if (timelined != null) { + + boolean placeWithCharacterIdFound = false; + ReadOnlyTagList tagList1 = timelined.getTags(); + for (int p = 0; p < tagList1.size(); p++) { + Tag t = tagList1.get(p); + if (t instanceof PlaceObjectTypeTag) { + PlaceObjectTypeTag place = (PlaceObjectTypeTag) t; + if (place.getCharacterId() == movie.characterID) { + placeWithCharacterIdFound = true; + } + } + if (t instanceof ShowFrameTag) { + if (!placeWithCharacterIdFound) { + PlaceObject2Tag placeObject = new PlaceObject2Tag(swf); + placeObject.setTimelined(timelined); + placeObject.placeFlagHasCharacter = true; + placeObject.characterId = movie.characterID; + placeObject.depth = placeDepth; + placeObject.placeFlagMove = false; + timelined.addTag(p, placeObject); + break; + } + } + } + VideoFrameTag lastVideoFrame = null; for (FLVTAG ftag : videoTags) { videoData = ((VIDEODATA) ftag.data); @@ -322,10 +360,28 @@ public class MovieImporter { ReadOnlyTagList tagList = timelined.getTags(); int p = 0; boolean found = false; + boolean placeFound = false; for (; p < tagList.size(); p++) { Tag t = tagList.get(p); - if (t instanceof ShowFrameTag) { + if (t instanceof PlaceObjectTypeTag) { + PlaceObjectTypeTag place = (PlaceObjectTypeTag) t; + if (place.getDepth() == placeDepth) { + placeFound = true; + } + } + if (t instanceof ShowFrameTag) { swfFrameNum++; + if (!placeFound) { + PlaceObject2Tag placeObject = new PlaceObject2Tag(swf); + placeObject.setTimelined(timelined); + placeObject.depth = placeDepth; + placeObject.placeFlagMove = true; + placeObject.placeFlagHasRatio = true; + placeObject.ratio = swfFrameNum - startFrame; + timelined.addTag(p, placeObject); + p++; + } + placeFound = false; if (swfFrameNum == idealFrame) { found = true; break; diff --git a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java index fe4a170b6..5bf1fe9a1 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java @@ -81,13 +81,33 @@ public class FontEmbedDialog extends AppDialog { private final JCheckBox allCheckbox; private final JCheckBox importAscentDescentLeadingCheckBox; + + private final JTextField fontNameTextField; + public String getCreateFontName() { + return fontNameTextField.getText(); + } + public Font getSelectedFont() { if (ttfFileRadio.isSelected() && customFont != null) { return customFont; } return ((FontFace) faceSelection.getSelectedItem()).font; } + + public boolean isBold() { + if (ttfFileRadio.isSelected() && customFont != null) { + return customFont.isBold(); + } + return ((FontFace) faceSelection.getSelectedItem()).isBold(); + } + + public boolean isItalic() { + if (ttfFileRadio.isSelected() && customFont != null) { + return customFont.isItalic(); + } + return ((FontFace) faceSelection.getSelectedItem()).isItalic(); + } public boolean isImportAscentDescentLeading() { return importAscentDescentLeadingCheckBox.isSelected(); @@ -134,15 +154,27 @@ public class FontEmbedDialog extends AppDialog { faceSelection.setModel(FontPanel.getFaceModel((FontFamily) familyNamesSelection.getSelectedItem())); } - public FontEmbedDialog(Window owner, boolean hasLayout, FontFace selectedFace, String selectedChars) { + public FontEmbedDialog(Window owner, boolean hasLayout, FontFace selectedFace, String selectedChars, boolean create) { super(owner); setSize(900, 600); setDefaultCloseOperation(HIDE_ON_CLOSE); setTitle(translate("dialog.title")); - + + Container cnt = getContentPane(); cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS)); + + fontNameTextField = new JTextField(30); + fontNameTextField.setText(translate("font.name.default")); + fontNameTextField.selectAll(); + if (create) { + JPanel fontNamePanel = new JPanel(new FlowLayout()); + fontNamePanel.add(new JLabel(translate("font.name"))); + fontNamePanel.add(fontNameTextField); + cnt.add(fontNamePanel); + } + JPanel selFontPanel = new JPanel(new FlowLayout()); installedRadio = new JRadioButton(translate("installed")); @@ -163,6 +195,7 @@ public class FontEmbedDialog extends AppDialog { JButton loadFromDiskButton = new JButton(View.getIcon("open16")); loadFromDiskButton.setToolTipText(translate("button.loadfont")); loadFromDiskButton.addActionListener(this::loadFromDiscButtonActionPerformed); + selFontPanel.add(new JLabel(translate("font.source"))); selFontPanel.add(installedRadio); selFontPanel.add(familyNamesSelection); selFontPanel.add(faceSelection); @@ -257,9 +290,12 @@ public class FontEmbedDialog extends AppDialog { importAscentDescentLeadingCheckBox = new JCheckBox(translate("ascentdescentleading")); importAscentDescentLeadingCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT); - if (hasLayout) { + if (hasLayout && !create) { cnt.add(importAscentDescentLeadingCheckBox); } + if (create) { + importAscentDescentLeadingCheckBox.setSelected(true); + } JPanel buttonsPanel = new JPanel(new FlowLayout()); JButton okButton = new JButton(AppStrings.translate("button.ok")); diff --git a/src/com/jpexs/decompiler/flash/gui/FontFace.java b/src/com/jpexs/decompiler/flash/gui/FontFace.java index dc616b3fb..9127df614 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontFace.java +++ b/src/com/jpexs/decompiler/flash/gui/FontFace.java @@ -44,6 +44,14 @@ public class FontFace implements Comparable { return face; } + public boolean isBold() { + return toString().toLowerCase().contains("bold"); + } + + public boolean isItalic() { + return toString().toLowerCase().contains("italic"); + } + @Override public int hashCode() { int hash = 7; diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index f43e507f6..835ccc757 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -615,37 +615,51 @@ public class FontPanel extends JPanel implements TagEditorPanel { } } } + + public boolean fontEmbed(TreeItem item, boolean create) { + if (item == null) { + return false; + } + FontTag ft = (FontTag) item; + FontEmbedDialog fed = new FontEmbedDialog(Main.getDefaultDialogsOwner(), ft.hasLayout() || ft.getCharacterCount() == 0, (FontFace) fontFaceSelection.getSelectedItem(), fontAddCharactersField.getText(), create); + if (fed.showDialog() == AppDialog.OK_OPTION) { + Set selChars = fed.getSelectedChars(); + if (!selChars.isEmpty() || fed.isImportAscentDescentLeading()) { + if (ft.getCharacterCount() == 0) { + ft.setHasLayout(true); + } + Font selFont = fed.getSelectedFont(); + fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont)); + fontFaceSelection.setSelectedItem(new FontFace(selFont)); + fontAddChars(ft, selChars, selFont); + if (fed.isImportAscentDescentLeading()) { + Font adlFont = selFont; + if (selFont.getSize() != 1024) { + adlFont = selFont.deriveFont(1024f); + } + ft.setAscent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getAscent())); + ft.setDescent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getDescent())); + int leading = this.getFontMetrics(adlFont).getAscent() + this.getFontMetrics(adlFont).getDescent() - 1024; + ft.setLeading((int) (ft.getDivider() * leading)); + } + if (create) { + ft.setFontNameIntag(fed.getCreateFontName()); + ft.setBold(fed.isBold()); + ft.setItalic(fed.isItalic()); + } + fontAddCharactersField.setText(""); + ft.setModified(true); + mainPanel.reload(true); + return true; + } + } + return false; + } private void fontEmbedButtonActionPerformed(ActionEvent evt) { TreeItem item = mainPanel.getCurrentTree().getCurrentTreeItem(); if (item instanceof FontTag) { - FontTag ft = (FontTag) item; - FontEmbedDialog fed = new FontEmbedDialog(Main.getDefaultDialogsOwner(), ft.hasLayout() || ft.getCharacterCount() == 0, (FontFace) fontFaceSelection.getSelectedItem(), fontAddCharactersField.getText()); - if (fed.showDialog() == AppDialog.OK_OPTION) { - Set selChars = fed.getSelectedChars(); - if (!selChars.isEmpty() || fed.isImportAscentDescentLeading()) { - if (ft.getCharacterCount() == 0) { - ft.setHasLayout(true); - } - Font selFont = fed.getSelectedFont(); - fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont)); - fontFaceSelection.setSelectedItem(new FontFace(selFont)); - fontAddChars(ft, selChars, selFont); - if (fed.isImportAscentDescentLeading()) { - Font adlFont = selFont; - if (selFont.getSize() != 1024) { - adlFont = selFont.deriveFont(1024f); - } - ft.setAscent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getAscent())); - ft.setDescent((int) (ft.getDivider() * this.getFontMetrics(adlFont).getDescent())); - int leading = this.getFontMetrics(adlFont).getAscent() + this.getFontMetrics(adlFont).getDescent() - 1024; - ft.setLeading((int) (ft.getDivider() * leading)); - } - fontAddCharactersField.setText(""); - ft.setModified(true); - mainPanel.reload(true); - } - } + fontEmbed(item, false); } } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index c88ca5801..003e03c8d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -4422,8 +4422,12 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } public void replaceButtonActionPerformed(List items) { - if (items.size() == 0) { - return; + replace(items, false); + } + + public boolean replace(List items, boolean create) { + if (items.isEmpty()) { + return false; } TreeItem ti0 = items.get(0); @@ -4446,12 +4450,16 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (ti0 instanceof UnknownTag) { file = showImportFileChooser("", false); } - for (TreeItem ti : items) { - doReplaceAction(ti, file); + if (file == null) { + return false; } + for (TreeItem ti : items) { + doReplaceAction(ti, file, create); + } + return true; } - private void doReplaceAction(TreeItem item, File selectedFile) { + private void doReplaceAction(TreeItem item, File selectedFile, boolean create) { if (selectedFile == null) { return; } @@ -4496,7 +4504,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se File selfile = Helper.fixDialogFile(selectedFile); byte[] data = Helper.readFile(selfile.getAbsolutePath()); try { - Tag newTag = new ImageImporter().importImage(it, data); + Tag newTag = new ImageImporter().importImage(it, data, create ? -1 : 0); SWF swf = it.getSwf(); if (newTag != null) { refreshTree(swf); @@ -4572,9 +4580,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } } - public void replaceSpriteWithGifButtonActionPerformed(TreeItem item) { + public boolean replaceSpriteWithGif(TreeItem item) { if (item == null) { - return; + return false; } if (item instanceof DefineSpriteTag) { String filter = "filter.images|*.gif"; @@ -4595,13 +4603,23 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } reload(true); refreshTree(swf); + return true; } } + return false; + } + + public void replaceSpriteWithGifButtonActionPerformed(TreeItem item) { + replaceSpriteWithGif(item); } public void replaceNoFillButtonActionPerformed(TreeItem item) { + replaceNoFill(item); + } + + public boolean replaceNoFill(TreeItem item) { if (item == null) { - return; + return false; } if (item instanceof ShapeTag) { @@ -4633,8 +4651,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se ViewMessages.showMessageDialog(this, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE); } reload(true); + return true; } } + return false; } private void showSvgImportWarning() { @@ -6250,4 +6270,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } return dialog; } + + public boolean fontEmbed(TreeItem item, boolean create) { + return previewPanel.getFontPanel().fontEmbed(item, create); + } } diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index 229c87159..efe30e35d 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -317,8 +317,8 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel if (readOnly) { parametersPanel.setVisible(false); } - } - + } + public PreviewPanel(MainPanel mainPanel, FlashPlayerPanel flashPanel) { super(JSplitPane.HORIZONTAL_SPLIT, Configuration.guiPreviewSplitPaneDividerLocationPercent); this.mainPanel = mainPanel; @@ -351,6 +351,10 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel return ret; } + public FontPanel getFontPanel() { + return fontPanel; + } + private void createParametersPanel() { displayWithPreview = new JPanel(new CardLayout()); diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/importbinarydata16.png b/src/com/jpexs/decompiler/flash/gui/graphics/importbinarydata16.png new file mode 100644 index 0000000000000000000000000000000000000000..834facf2e7550922edc9d90ecc10e5bc6dac30e6 GIT binary patch literal 5904 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 F{{WKSH6;K5 literal 0 HcmV?d00001 diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/importbinarydata32.png b/src/com/jpexs/decompiler/flash/gui/graphics/importbinarydata32.png new file mode 100644 index 0000000000000000000000000000000000000000..1cbf5436d0c5edf3635250b3571154c1b9757780 GIT binary patch literal 8190 zcmeHLc{r5o`yUZPh%8w$*~ysASjHfs5Rzn#j9D0r8D=mkSwhLam54+_N)fVT%@UGq z*|I0cu2abV8|s|Xxqjd4`d#O`e&7GjT-W=~`##U-{yg{ndG6<)=b125lhX&;gxCN8 zz(E6jT{HSOaQ9+mrr#;PzTW@z50LCh!V}zZK@Bjd9AS=oB z_T1xxAv^F}9JRoDj4G7{EdP4>;#Z8!5d@m7_v}R1G3HHm{}0!sCs)R;4Cic*$L%5zh6{mb}T4)r$Mh z4NDxcVkRcfHU_UvEjO`We#%>wFVfn@HnI_4-TygXZ1`n$rBlCC`&>pta9-Do+~}wG z_$QEO`Z^oXHsvt?mcwgTkB`(L8Rg%)UQAtF>S2lL(_EiU8M&6avBb!Wu~Nhe9g6^F zztHDIaFlU+UftrferzN+isYO-SJ%q#fBR`K*{Qg$r3hlZRbnWlX=gtP@NAP65aF4)E$j(?Qk2|MRz?Mbz!w5Z*=NI7oi*b!%_ znAP3sk`v_YVvOiDb0tP1gyAaJh6LZ+aM}6J&G^og-LbzS{NAblfkY&#B`32Dg3Azt zx1m~}yZ}|FciuW&R8g5{toF?`Tt)PDyrrYrF>qb3^;Tg$lAZPF{E42~1^I$q4

)!s{hT8q>sZ7l#Le~wdbNvQf8!d#V|Iqn-Z2DBMqKuPmIB8E!I<0 z6FuHt7gF$GwPsZHQs!jtZwV2J>SI~#5?AV9>i3-7(cf@CyHh#kKf^j>_3nPiBT&(V z^LLAxK7;2Tzs(#U>*x-xI|d)}_Kx6UomjY%O5`b0oxFx>Tk@z@X$kLA6{R6dG!p~P z%GTOEermb@plE)qL}PO9W5rOr=b3GNHc=0)=N;_&4ifPUD3uz5I_pjO>?Q zXbg~gdZBH;^UYZ{C44l4!uNzDX0~pKW*FD=umuGRz>lK$8|%x`o2zqd{mB~VJ6=#ZBKsB9AcL>(=unI`I4Kp*+-qc zSOOWakf2c^1Yg0WTAP4T+B44Sb64%5XQ`dtx-xoLdcu4@1l)h9s zdQZMXH0jMadQFnG-i;U}$1q|oa9bhh(C5$ZCDb%0p*6zQ8OL^Vo_| z(Q!3+vbNSYp03P9+o$L34jh*-@bF@@LeflJACoXe!3Lj}b0KOMB1#`^>^Eo9p?K@C&q2+q2$6(z-hHO`KmvUN&3-UyoRON1iV|u9!})Pi8M%7dQKkCrL8hff zbvH+aQ*vzg%O{UV`?9Ye8Z7$qUZy=bni^+UmsV&~z~YSu45ug!)(p7m4L{x=TYb9b z)b-ZyZ)V37QUqnnKRo5bOMd-k$ZAFK1Da#WE|L=|aSNPu&r$x{sA-}d#9t$R~xlycK$v? zW9n!v+6{k!J(|I_U+Qby&HGumA%%I^4S6N$BG4vF7Dw{ndS}lfLN0$dnt_cWhP`vwJOZ~H&Tv#9K2eSJf+w;=xc zF@GL$8_N@U0e+9{xR}%!+Z3eTVW>|yXS-C%{{6zulv7oe_g3-_B_^l?1L`iErwo(i zWmnWIVBE}yEnc=vovM&n8e#0MJo~NU0Tutr!ON4WsRSAnHWb>@?Unl2Ju@a4(`Yr#=|LSP|Vq6rR9GMDkv`9g&9e%1>%Ej(aU9`&^lHV@0SZH6+a*{ja!&D0(K zP*jwsJk6Y^d+5%shG<0%_tyl=u{W&Gy^m@kXr`zmCjc1Wy;r zyRR8-Kej0^zT3kCHF1xyI!?6g3f8t(1oR*HK3jj^0&m^ibolx{p%IU&eJy|#@w_LV zGWoAfAAhs>XlcAwYxr2mW#(LS>yYGRhD5QqWB9A!7_5oQZw=f8PT7w8jMer|Pmr3x>2sSxC1qRYzjt_cmk1IMrwXrd2lVM)A*T&CKTF7ybpm>`L6P%y(~jlh zy`dO6QPOK^Gx)HkqaNyfUOKt;HOadu$6L9{Zy$AzH_?r;_uThVgqxlTjYhcSF(r*q}qinp$hfC8QVq`exa4y(Jo{%?}1zXP4--l-p zK;K54k>&G3mq^G?Ikc!_)xsxjl~P{wbi7x@@{?n4czj_z$v_jz*g>#@JZq2`FkjK+ zmZI7CPTa|GL9VEcFAKvH3!*?Jc_T!HG~mLE2y>J)o|5M{%BRf%41m5heA~@C-N1or z>eaYgl)V%QRwKjH4jp=aQ{|?UGAQ+{rbkkuWXSh>w2$fRJX)T1-fNMR z4s@VXXrz%#nyQfkzq-|eg9XfdoG^Yf!zBTXwX;wqc~~4rd?=UkN6S8Y`moG|BIu!T zEKpMSP0oV|HU(Wmk3KXuV=L)~|C=u|%~J7s9H*l8n?E?|xjE{;RAKu9f|!;LaXhga zPV|oe1lpxrznovh47#TQww*=|T{rR$I;_Nh^R*2ZVelKQY4Ea*Ukzv#byzaE!_geO zsT4v_4y{a53&YmS6Xdq}r^V4-EI=JQ&o*B>j1} z87vOmgHT;H#I1}?fjT5l98gJ7Nf83lqY=De;+kwglqVLCG}ArxlY;)HA?{42l96Dr zkB^U{4_uMt=>&$Vsi}b>Ffa@Tq9Z_*%kES(4dhOd*roWvp^KwnJPBkff#eR{%D;`DytAN~=^#>RiryHkFuK-U9ILzBT!MF^Nk1pjJ5q3U_lNq#!?A1x^6^fMCJ z3`Ze(d17#S-Z*!v#IF=s%%ApTFHg6^;3IrVFh{mgeAWCQ@M-_}C9HOlJ3&mMa0zE6yZohi9ONFIV z!SN701dd05@CZDeN)B)fjACAvA0bfC-Z<=@pLDJtT^MJyyAzIH zKYk|cAMJ$ykPOOn;Z*6Nf#5J@C`ic>rvySPt0;jmN~$WV%6JSOucG#Mb_xkk^+9{$ zw4LZW(zT)|=$=+U*`HG-_jkOHGj4Yt=#qh;5YS(eDT{-D1`FP;7=J{I0{<^PPhyUUTbn1Tx`A7QxE7!kr{UZhb5%}Ni`d6-h zq`*G{|C?R^Z*sByb(q4r(|15V^rI432qj2AW-&XSIjy^Q;PO{n>+PgJ9U$vlQvd*V z-rb7Ik|7&Sne%z1RrZ|k-lzVJ=ipthf5bk z*e<#d)TvyM94c*=QY0>!bk9$7WNqQg}NduvOI8^f;GifkoWoQOim$5oJ>8Ieva0U6pr!&ukK_0wgW7nYN2=b)D}t z(=x8-!NQJ|SHP`q>s=y&8iBGfOmz3V5H&WL3TP zT5RW@QP#>ed=u~sjbmgL+E|3Nj}BO?;NB-E6-od5bg}9T!F%O9m)O?AONM7XV}*+q z30W(gT%70tL!5gXXK#duES5&T`Lc0jfSt-P*~6q;{Ndqw4{7(aiV^xZqws{;>kj2M zjD3Z&JC7IPX$# zB`yy#McNdokZq6^Cpj+MS3-n0GQC!6&Ea9K6H6?U&!37-P0p~omvu2e zc(Gw%UocevNa;&^5-c$VkGxcG#+Id^a0YG7f7{IJb|g1XJLOB!jSolj^Ew7zcL|NG zz8^R(w_n=%iZMfD((NywLu8AK^p7Oej4>@o)C-20F~^K?G;^aFl1g-&C%KaIQ`#oK zg02R0@94nnYRDz#8U1efUY_*UhB~Q<4XjKy+3qD`z`|P6t+=qXiaW@#%;-h`LzL~S zA{4J8SK$4YZ*%>ABZ}{~=TVE7b^>lr#293Uol=Q0YCP8>ekfXks6Gcw@+ELk5}6Oa z3|vtPaSU`RHY~Q0h`sqW%TE0+=*|k@nhZnB=+|grm9>_w)s7sMq~v$8?E-gGK^|W% z7&rpK51Hg*S&J5L$PKbE+6jw4G&9gFSjK!?Ugn9^y}Y>2(k<)-=rIW3fFxr!J8^Mg zOheO3Iy#JfxAhc0G`xy_i;8CFW)3r~xtJ9?d-?DgDR<+KkIdy+#t6LLd3Mq%(YU7; zQ{I?cxzl&01m$tyI@4f5mm=>kul92kuPphA$>C&^mp=urZML)NfD!;5F(0^f4$-ue zZ_7l)vRgf?Yh~m8{I$%|b8VARSY>6qS5RnzvOdFpul*>K0|u)y^6^^0Rn65F8|iPs zF+%h4Z6*Z;F9p=88=aqC_%f*aP3lGX#bjolW>DRnk$CmJ>a)p?@b-A+i9v43_~vKP z5p&~nWj)Zh54*ydKn{Iw>mp)e*ZZ_rA|t+ZW}O2Z-S}Pbw7uA5OXT{|ngu2Q%662$ zs?Vap;$+wTfvSD4T`G@$qRJKUV{-h8K3sfTW#rpMK`Fx;!&)<+HXd9mu4w$eHJkbB za_U?z<5dyzprdLv@4BqudeztzW+ZztN`OY|J!Eq6h+f~Zt^m?#eb2e0Lw-zzd13Ce zl!;I6eaxkKX3y<8BB3Jdv#WxepN>>f+K<^+lyFTyDar-dZ;-_@C2rh2wMr`SH(1FM zg99yX4-QT)dkebEn~~ee3-YLIG_59+x*^;9HC768J|w>&jLdc9RDMtbm9d~iU3}!b zZ0?6Zho#!H-uC!>n+7jo)W!-c0$w0qihu`VYICgGUZk8{h@_`O%ojSAIIzvQ9&M|uyu#53kgU5Rc~wSTP~2+=OoPQ?`&RFK z0oCStZg7$uUYHNdCv3f{n>ke_I~y`&vp-Y$GM7& z6afI3>+EFb3E$^QE_qq_U+48_8UW0G5KZ+JdD0?5zJM3R4uwFGm=A$a6gvn2q8@hn z`0dj*P?}z}JAak^;i9UAWd+yTvhLGZF74uy zLdWc+T~VF(?|@xzRSm)^-M4+WSvXl+cC*vYDg0@D>0C>nSA4KZaZiVRzOVSr(+^=2 zH@pM=5GV)t^zn``$5)WelIVAb1`68x?)0tSvMPB)X?3hH;y}!u`}T7cj<}Z}i!rWB z3fG{nXnh7Ct%DL&mOl(v^H)5@nN|<-X$i z?5s0V3{1taudGAx{xyB3qgyV1N<+F%(Ww*l;@{MBElcx2J=sq{x>H|=lT!_Q-tmkvv8hra2@2$_)DW%~D z{bWvv7HF`*)Bq5jr!ku!ydhUyG%pHML3}-XXfv8{4no69!s>L9<~7VB{SKuyu9uUaEPW zdo!+YUNL&CCnR=X2&p5Mn)vuWm2Erp(8#Cjw4*A0@XfzY_N#2{3JKdEjMHkJ0OCK& zT1}|h-k3|(xXXOl6wxxMC&raTawbZS+!EW~xv55 zgWvvxIi@ny22N()xLfEdg7!PErHERF`J>!OWAW1yuB|<3H|15`WiDzBXFRgJUpIBc z;7Et+%IrMPbGVYa`pqwnq$q{GAm{NmbXj>bEh&SArxt`|PW6MC9k+V;XK(aOJXDx? zpuBESZT6&rwkzJA#)xMw=N-u%pZrH@QU83;W=i+Av`U?(yaXPt^V8XJw27(LuKb~+ zPdo2)OLKNPcphEX>{DPqzk}~Y-SMaFEFDIll{3pSC0K_wNB2bY&PK6|-I=M;V|Tgv zp4!0i=iUo5?EBImc0L>$h%Jm*rak+b#{BZ8&>hXIQzoyd@#8f+uc+5N6X&(N^kgc@ zE2rNkif{K7L+1@PWFB+mC|o$)S)`d_bLg3hZc@6Qe{OLyp-8YTgr=RPf4W!n+Tc~~ z0=7cMG4-3SA1hVUH@{fvtdVW3+3)F4xQ~-TdQ?;Vc)qred-sygrnHIYUK^9*RThR- zWSK^g^0p%C_u0Kb>KU-s432tqNo{su1ijyfiXCeoxY|Izi!&Z zq^+K~DR!(@E($*QYU1Y7<9c4LvPJ_zj&v_&!-7!g?JP0aMY8sYv1l32{Txk5@Q=-Z z2qdSxgO(P>;98p}U8n({s@^+YMQK~TE=$PVo^tMdwNz!G_44}5_09kwmB_ZW^>DVe z{o3T=)}Fg%w}n%km3I9`uOd$)W%c=C4IcHi3B}2WsAuHWUHl5y%I$HjE^xNZ=~K-a_gSzP`#4*wRVfmn=kGdTQMSx+qprHhpjPKa0kVr z+o3JBrK6@k+;7iB{LRIIqt01M*LQ!!C)!9wSsvoukeaHn;y1oLQI_5!2igW89|Lkp zHNm^jwp%>vYI)F6&00S-1@w*z?!7Nq~JXGk6>m8k0wdOrkh^_^k{8 z=9W=>8Y2V}fpmz)=2{>|s;Utnn`wdYAyCj1zAY5Yc8V52UeWGUMsx^+#6(!GQZ$bu z!vGveL<6HZpM5Abcqvpe;`Tfp`WE3hgGSVaxXTlS(P#6-4ghFFcSS%8jKnlfN5iJVI73xYL zW-#m^Aw$6Ci`YCaD8Z!BdEp`p1Oi?Mzxv1FQz+lyxxz0jzF|AXW?5a8=Sm zfAmTM#e|_qOf-{0FoTecAQB0Q$3g@ook=4g@pwFj2;0Gt@H5^p8Ds~ZfJ1}R$>z{l z5Q@)bP1}$VPPX=Nwm@J_(BEe~LTREPSOMMxY%Y@*Dg3@fWpf}e5lzA;#*}16GDQ<` zI2?(9Cz^d1@`eOLxE3X-7_gjwrj{nDR2X1-9*%}=D}ZPso`A~Zg<2pa zPJt55Z_5;TLosP0njK99!Jud?j*LN*u~;gaM8;#u7_2cGOGf`7&ttNK#Q#ZJvVB1F znWQ_hg|L0`^wi9r@`A!cVN!TsY) z!G4`*|C?gKlT2}F97IAwI4m8`8xDgc(TO;uDV82YClRqYJaMKNzM%_wL83^S0J3Jm zJi=VT1vn%YXJJG8mHN0j3OzK_kCYhC`sf1dEb%jIYs}qy8Ts=FFX z|24W4zaOR`F8l=)2_Kcl7W7rX$1GX8tE1iYfh&$Q+1?C~6!=c-ga9x{RdPuI`*Stn zNjZ@-#a?buQC-ex?u*N2!2lq=$l1=CO1xRWXQPu>*urbo)iEQV0s~5r(rFT(gb}cwD&n8{XAwhlq8_nc}_gv#dVMmu|%xdD_x?eru zJ@I*nrc__q>o+)5LmI4`;9rt^_qeuHv1fM?8r7Y9VDQ=6G`y|uRbb8XVEYRNS48!O zcPO&Xr=_#WFGogO?K}S2sosJw{KJZTbjZ2PJm3My;9{MCKm|1Q{hLDtMcUdc0j$_d zE-M?AmW3UA+i#cd|GaNSWJ}|Y#<}HQ8+~F|yYASVm4+C(7dPa#=<%X*>b%O`p>Hcv z+Q;k(dp4dhm%CfIN#80rhBdNLG5Vy-Kfb*5l`;bXnXx;Ip|@qr|8TDZla~~>=!kib z)oQGobma~V;?}*)Da_VtrsM~*C`!O%erb!wsuR8^`5$kTR!kMg{Jo|>AcUPLY*m=m z-z%P2b*(4;c+x2NULGjW`t!|roAMkPlRKwzW`jD9W6wC$);>t;2)P(`_tuzU8fEL% zBPC*W^S0iLB>7w~Q7!9f*mAe)lcsuG676BhZ9gZKzDJ3gFD@^p z1M?QWA1i4b86MPP)Ke^~a~mx7y1Jw)ZQ`aYIg>rhcj*MPOQgL`<5gVa)9MB`yjTL< z?b49Dcr&kvWn6HnDE+U8^h=3G90Rg2b zO{6!aiwXh?2ns0e1-y0MZ|2RNdB6W|W|Ew<_gbI5_IIznbJirz*hrg>hLZ*a0@3N} zXqXVc!N+f^Q^ZevVBl8}=yZ4>(t==u@&kL}JRPxa0GJTq1%Ls6tRo2IKUth@nRXsd zuW=L*4=2@Sut|PC=H>zI%8!XnDT9eNmDO6qM9d_08lJyRnL65A_da?nU~*UA%Ebd7 zbhWgYRY75Ft|~NyGQV9$X1|hT?p)pd z(Y%*v7C!*l6zTr{^kB33^pEAp=6t5GP+Zx-)qVd^Hsv*rkoadI{g&TsTpd}I0JXe) z&8Jzo&)&Sh@&^%o3?O^$+8l*8>zz&QE7UAm`HJ4vb86(7OePiuF-+T!^H8u3=K6%_ zJa(syRZJ$Mb?zOu)?`2VhvDzjXwtSKc?{<8)D!4i`D=kzA9_T+Txn@p6KUo`n${2J zx%HzNfZ^>c&8{s*zs`$hMM_|JcfMNem71+$c#|K< ze%tE~QQTkBUK^-~%{_A!qBFPCjv2Q_^ja9k_2!fa39it4gPm{rjNx9&3rjL4irv1_ z&+)6wdDR+M$9axeS2v&-*NNDVEL!aJ&YgKfKS%+9p7~*2ZvfBVA_Zl*wKtZ~PC}Kx ze42cW{$^LzJNKsXj1a+dW%`2cZsO=vL8M#5kgVG$_o}DhK`{=K__~7H3O*_GtSsLF z{T~a=%TU20E7qiGN=eqjC-|kMZ&A)0_|opO!^x_{$39g&zxIG51)eiBEpL9`ZkcVA z5YJT%P1s>KrxLW$wt!D1iHzrCP1bzaS7Uc>4%_gd(J15u zcdH^JN1T|%XGL7`tTSg^Gw-k>IeR)Z`SnovWqcGp(5O{I1-49i{ID;icQhR{uW#0< zGM_;kw*F&hJF#}%4bx>Cba>;|VFOS3dr4PbSHkeCrqKZ#Aw5We=N%=!JSXQBse&*v z)HJ2tz4sC_%`vlQxG!4pfnIsPX-qY~5zM3iJWU?Q-7V2TBh4p?*;JA;i1|#bkQ3#D zdn0UPK^84f!t+#UIoaU$ZruINh3(z89p%BP5N}npscyeH4b;qKm6&&8j|1|U+)oWo zo6+k8+|RfVr}jm-TXVVyvCThl?kXkpaG7a14~jJ1JY%Tu}Q;C>5avYsuNOsj%3jeEF!nVvS;D1f7wKe6+Jjb3*wm{23*#AIapM_yqf8D&EDI$apYp zUzOdT)CfV}Agd%YwxqSvEyc#Q39BEt%Q?mwEuH)t+}E0OS75Wdu+XTbAa1WoF~D6; zYC59W0S-tt3aK0Ol>~|DG+9*z0R(Q(>c?M8p9+)ei1O7s6=x4|89=n6tHqNN6l!R! zLm;%wIzp=Q*%m|ey;YNl(-g|rD^dUqN6_tnF&GC=!f@OGKl8Uca*ob6YdprP-Bnh) zrT77cN_xcStBiX5=7%|haK~Eh?7PdbSILi`AS7Z)ZM+F8A#^n32jU z?#Mo4EQqhm)%1SKEd7vNecS{7q*45~?0bfFv_~TM*^CS$iUGq5J|L%QGH}2UmI{%z z-7~L>lJe8;J2Sm(OpAcjqbEveZ7(kUafsvq7@|34VpCl$ zSacrqo_gqxQY%w6{c0aoRIv;@ZM^uE;_vX8=8DVlZePydW?lUh&U~ry#RBh#xm^Fm zvP?=4bN01>H`Uv%FFw&uGo}{Ck~IZBNvASyvT)8UGcpUJnEg8PBg?u%+gV%G-->i( z7YJmgRjnzreYJHlR7i3;iT&Lh%O@{ogQQoQ?IWgL7sqvabWP|ARkzjqqU4~H>jqqj zFVEUNoc@(7!*N*6oTaxVaqbcGLusoo(Fw&7d%29rv8&4E6M|(L6E9i!knaK&%Q6Hk z7p|W6f|&Q*94%gw(;xUM9Aq7m=QWo&&*QPs5{i7O{-xk0zJRej{+5rkGQ>tJ0Z}aB z^C0{oT_u2)3UDWQ5d5+RP5ZYiY$L#a_a`g{n8?)}X|(QC@scRVBjWj8v+pkg?ckoT ztC)K+=7hzJgz_u!h=cwI^`+n+FfKAw<47~Z{<(2(e;ao$s)_B?!69HFA-@C zHEAdrJI^?MSpHfs+AQ6k>BaIOt34ZoRdKM>B~neYx{yAdlHovXg??K;7s z6>DaAx9eW^4aByPbv^Fu51`W;tjK&5eeLb`hBAD2i;L3k8rL;QNhYdQ{Dz8nzj0}K zJii+K1*vcE?QhpclJu2avA3dW8}G{zMwFN)cgyI%43!O;;_??3*yYFTI`)H`_jj#3 zrZnwy-EZ~U3qnQ`5*>oO^xoK+FnVt}C|&;6+2lyG;L7+>xFbH;KTE6Wl;mu9L)hNZ z%Zad>V7zs|Dk{70h-BsKu9~l6zbyzv5{*??H`Y~G|NU8<_ynFClB%ThT!p*C&a~L% z0zKlOX6yZ6Z=p&=FtmFwde&3l5ijrT1!-X}N<| zv1>vpIQVJ8rr0_@EcvQ{C#+S7aX@mWI#w>$Nfwf~b9(R4YW?+CJC8p?eMWq-wE&KvER_WLEDqM zFCDE$;;($y^Cihay^2@g=ZeSIM<~JSwvagxWlXDcYR!bw?99lUsTL=zg9FgQ25$7n zgRvoE(d3II7DpC_1_-pLyEqEt=>UlPyL%CfClE+c+20F=b_EDv2fzvIp~Sb|)WQeG zVwCvIWelN)Uh04|Rwob#m_>yPF3d;jhGZ!bK3T zkDDdV><9lIpSzc#;U9Pp{BJ4{^^ovKc}Yl$LnYkZCI0GxCusT-A-@ImA3g9$ zVvQ+b0^mJ;aA-i&7w{mQ|0@E6{=?tP2j_M&9Sm9ma0A?lrg-A0l7AagTi4L|507IB zoUra*CtgIc|7JYzzi9`QvF?K@{9ElFZJ%IJVc>3Z0>_TGQ0aF6%SWih=xEx#- zDkCE=Ckuy3{*3yBXa?Z$#9Tb4NK|aW6wXj4T&2HgCd|bPy~Pog~Fr|l28N;hJ?Zq(lCUSoG28Afd0ka6N7aO z_`j@=w+~qH=c4Oi@x<{1PMUu1DO14v=iSd+H|)t~0)tPs1pmvNo4)( zLOY{8oB-na@ms?F-j4kb$sjK!4}+sH05O3a0f@AWG#Vl=DFZ;{;TX8Aq&y0chfDpP zj`wsV_@QussuNL1qE^HNJ<$p*{M%BA{N3Kq88}`CqGS+BDCAGcq}^em~oYM;GxVl=$N){7tXpL+8Kv`fVNliz5)x{|@qx^!-<^f93i| z3j8DEf3xdfx&Dy?|H$~??D~I`i{{T_3h*F40r?S2C5z_hZ^Sa|l!Lyu#!0~y2LC=W zOuVA@(y_!7|F~j0ev^Q5a@mQElmuNvP0A%2R>}*4Dxv+tL`O$m4OOJY^Nt%K2ALB) zUCK+jOS4P3w$nHCOTjEf?HfQJO=0*QR=b*K2IIhT-HQ+XsJdd0+M#0S#-cYX_XKAg ze$;S`8f95E`MB4>GUsbJZEHF@pynQBz85x=`E0}$cMdKN9L^8VpGJ!I8R3os*6{t` zr`Ol_4)XACj}%|fRtlIOetjBfikH6kTE@mGudU!M+oi+(@)i)Iso}6AgUWUNJ<+6r z@wB{xk>JG(lsS9nPPvVcbaPDFTu}cj0?6)vm^#{B8M)FypfG6M_s-2xaYm4)ZeoFFp5ZYU zR$xl!209-XQ|$M!shE@AN+VD>h-I(79ZG8Iy(hJIK>B)dJaFznPg63ih4DqK)obZE zlgMW(q%pSYIv;LU((aIfv-amRUlvB@=18zCZCtN}<^T@qq_>!fp!dL&!4Y1Y?EsS3 zJhz{;1QZ5ebP6g=q|nmQP!ldT)`PM>?(V}C5SG%GgEuTmFk^Ls>kHqXB-AK+O#Zk_ z>udK5EA?I72tjhK(HCzA&*qq=e4>z=j3s2QylHwCc=qTMJ(E;tY_wYT7hyfUYB4eW zI|?HVFSDdZ1dMyRlADp=Is!ycy;?`v9pBc<*$-}9*P zi_}fYFI{d>oO0=n-}SRg+^_&W4|^_OyWSO~-pQVmp(Aox4azNh^RsT(&2Pp-$e0C~9kVfw90 zmHv;iFRFv1i<;iiL>SGjwlXjza-4U+8>+0QSHz%0-oB_JJe8rF;x|KhwzK-u?NVoZ z%+lg8hfYeYHv7lVarq&4--4m1H2ChS^ImKJr6^5DB!$sNoK4LrFRCf2VCJUjSKrUW znuO#R)zlk#Eh=Ittc=8AhY&+}G}baPDVa|!yaPQCG?`ycoBs_03^ zpOSWen96AmI1`Ao;qVZr)f&o}w|2c@Z@O9MWf@1letTBCU<>Z6{7nJGc~qC`{Gk}V zG$+JHH76QgSsbukDQsuZf?614&Pn^qNxHho`zv7esD9n)>g1VHyRjETvJ#+g<+rMh z0%si9Ze02V=8c_!gqO`8ZtDv~2Z;D~i7m8|Kil>V3~W5BHrxCZC_tX>WoyMG@uYA1DF5)+Na|QD35|K!)H}kH`b=e$cCXib?6kvEQ@u~rr&^X< zR=9E>yq~mfzH&uv(a(i`aClAgwTfUb+G=oNYjdWH9{kwwiGv(Z#Z=cX_s9kpk)tvf zH>1@Iiq9KvJl><)KC15t8=E+l$WI3ZZ32_!Y^h(8;+2BEyqShW_r|P2yf%|jeq-mj zldsuK^?v0&psp>6FR=LW$u+Z*;5QSwpcW~~&bcWiE&bwVh;=B%S5mT8nbwrF#F2}; zp=h!gs{-k;(^;K{`NR7VZWo@grAKFq_?dL_^hlc4dK7AEY7(8*3i%1XKDdg5(bKIy zVCnB47ArDHJ;3-r@mXq1rFs@Q%s2aqc@45lptJV7MoBuz_1)(;%#R*?fBmv-6MoJQ zA<3jx0KFmZcW1dD1@`JyQl=t+o)wnJ>QhHOAc@keJ4d0Gq@3Q`?&MoU^6Y)?yhi+I zSKm5~np(vMTdbJ)&FdZ$R2>(o&RId}v{7#ZJ9YQF6r;vlpwLp$3gx%;>kmU0mZIRS0UrCD@$Q5?;H)t_6nc>eJ*g zoO0Kh<8y%1L(nyw9Iq0+`(acY zRGLomNl)aU-mptIdwkbmbv!JERD?qBLfS%3`k4zN0()ob9n!hv{XZHSY-RagAbSzX z_4>$6)K@7w?m4!QoI?dQtdlQ$Ekcw@P>)^?dM29;LsqH4eKD>mtdc~D$u)Q(qKLn) z2^33miXksI=lwo&E6GQ{hDb}@otShHSop^ykSd31`k98_ ttffile.selection = TTF soubor: %fontname% (%filename%) allcharacters = V\u0161echny znaky (%available% znak\u016f) ascentdescentleading = Nastavit ascent, descent a leading + +#after 19.1.2 +font.name = N\u00e1zev fontu: +font.name.default = Muj font +font.source = Zdroj: \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 39bace7cb..908841773 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -1195,4 +1195,12 @@ tagInfo.textureFormat = Texture format tagInfo.padPixels = Pad pixels tagInfo.nominalGlyphSz = Nominal glyph size tagInfo.glyphCount = Glyph count -tagInfo.fontCount = Font count \ No newline at end of file +tagInfo.fontCount = Font count + +tag.shape.create = create shape from file... +tag.image.create = create image from file... +tag.sprite.create = create sprite from GIF file... +tag.movie.create = create movie from file... +tag.sound.create = create sound from file... +tag.font.create = create font using dialog... +tag.binaryData.create = create binary data from file... \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index b58dc3d9a..7d4c6ea9e 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -1172,4 +1172,12 @@ tagInfo.textureFormat = Form\u00e1t textury tagInfo.padPixels = Zarovn\u00e1n\u00ed pixel\u016f tagInfo.nominalGlyphSz = Nomin\u00e1ln\u00ed velikost glyfu tagInfo.glyphCount = Po\u010det glyf\u016f -tagInfo.fontCount = Po\u010det p\u00edsem \ No newline at end of file +tagInfo.fontCount = Po\u010det p\u00edsem + +tag.shape.create = vytvo\u0159it tvar ze souboru... +tag.image.create = vytvo\u0159it obr\u00e1zek ze souboru... +tag.sprite.create = vytvo\u0159it sprite z GIF souboru... +tag.movie.create = vytvo\u0159it video ze souboru... +tag.sound.create = vytvo\u0159it zvuk ze souboru... +tag.font.create = vytvo\u0159it p\u00edsmo pomoc\u00ed dialogu... +tag.binaryData.create = vytvo\u0159it bin\u00e1rn\u00ed data ze souboru... \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index 2bc0544e8..12de08bd9 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -47,7 +47,11 @@ import com.jpexs.decompiler.flash.gui.action.AddScriptDialog; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag; import com.jpexs.decompiler.flash.tags.DefineButton2Tag; +import com.jpexs.decompiler.flash.tags.DefineFont3Tag; +import com.jpexs.decompiler.flash.tags.DefineShape4Tag; +import com.jpexs.decompiler.flash.tags.DefineSoundTag; import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; import com.jpexs.decompiler.flash.tags.DoABC2Tag; @@ -1396,8 +1400,7 @@ public class TagTreeContextMenu extends JPopupMenu { } private interface AddTagActionListener { - - void call(ActionEvent evt, TreeItem item, Class cl); + void call(ActionEvent evt, TreeItem item, Class cl, TreeNodeType createNodeType); } private void addAddTagMenuFolder(JMenu addTagMenu, String folder, boolean gfx, TreeItem item, AddTagActionListener listener) { @@ -1415,11 +1418,11 @@ public class TagTreeContextMenu extends JPopupMenu { if (allowedTagTypes.isEmpty() && mappedTagTypes.isEmpty()) { return; } - addAddTagMenuItems(allowedTagTypes, folderMenu, item, listener); + addAddTagMenuItems(allowedTagTypes, folderMenu, item, listener, folder); if (!allowedTagTypes.isEmpty() && !mappedTagTypes.isEmpty()) { folderMenu.addSeparator(); } - addAddTagMenuItems(new ArrayList(mappedTagTypes), folderMenu, item, listener); + addAddTagMenuItems(new ArrayList(mappedTagTypes), folderMenu, item, listener, null); addTagMenu.add(folderMenu); } @@ -1427,7 +1430,7 @@ public class TagTreeContextMenu extends JPopupMenu { private void addAttachTagMenuItems(TreeItem item) { AddTagActionListener listener = this::attachTagActionPerformed; List mapped = AbstractTagTree.getMappedTagIdsForClass(item.getClass()); - addAddTagMenuItems(mapped, attachTagMenu, item, listener); + addAddTagMenuItems(mapped, attachTagMenu, item, listener, null); } private void addAddTagInsideMenuItems(TreeItem item) { @@ -1440,12 +1443,12 @@ public class TagTreeContextMenu extends JPopupMenu { boolean gfx = currentSwf.gfx; if (item instanceof SWF) { - addAddTagMenuItems(null, addTagInsideMenu, item, listener); + addAddTagMenuItems(null, addTagInsideMenu, item, listener, null); return; } if (item instanceof DefineSpriteTag) { - addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener); + addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener, TagTreeModel.FOLDER_FRAMES); addTagInsideMenu.addSeparator(); addTagInsideMenu.add(createOthersMenu(item, listener)); return; @@ -1455,10 +1458,10 @@ public class TagTreeContextMenu extends JPopupMenu { Frame frame = (Frame) item; boolean insideSprite = frame.timeline.timelined instanceof DefineSpriteTag; if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST) { - addAddTagMenuItems(null, addTagInsideMenu, item, listener); + addAddTagMenuItems(null, addTagInsideMenu, item, listener, TagTreeModel.FOLDER_FRAMES); return; } else { - addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener); + addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagInsideMenu, item, listener, TagTreeModel.FOLDER_FRAMES); addTagInsideMenu.addSeparator(); addTagInsideMenu.add(createOthersMenu(item, listener)); } @@ -1467,7 +1470,7 @@ public class TagTreeContextMenu extends JPopupMenu { if (item instanceof FolderItem) { List allowedTagTypes = new ArrayList<>(TagTree.getSwfFolderItemNestedTagIds(((FolderItem) item).getName(), gfx)); - addAddTagMenuItems(allowedTagTypes, addTagInsideMenu, item, listener); + addAddTagMenuItems(allowedTagTypes, addTagInsideMenu, item, listener, ((FolderItem) item).getName()); return; } @@ -1513,11 +1516,11 @@ public class TagTreeContextMenu extends JPopupMenu { if (insideFrame) { if (mainPanel.getCurrentView() == MainPanel.VIEW_TAGLIST && !insideSprite) { - addAddTagMenuItems(null, addTagMenu, item, listener); + addAddTagMenuItems(null, addTagMenu, item, listener, TagTreeModel.FOLDER_FRAMES); return; } - addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagMenu, item, listener); + addAddTagMenuItems(AbstractTagTree.getFrameNestedTagIds(), addTagMenu, item, listener, TagTreeModel.FOLDER_FRAMES); addTagMenu.addSeparator(); addTagMenu.add(createOthersMenu(item, listener)); @@ -1527,25 +1530,25 @@ public class TagTreeContextMenu extends JPopupMenu { if (parent instanceof FolderItem) { List allowedTagTypes = new ArrayList<>(TagTree.getSwfFolderItemNestedTagIds(((FolderItem) parent).getName(), gfx)); - addAddTagMenuItems(allowedTagTypes, addTagMenu, item, listener); + addAddTagMenuItems(allowedTagTypes, addTagMenu, item, listener, ((FolderItem) parent).getName()); addTagMenu.addSeparator(); addTagMenu.add(createOthersMenu(item, listener)); return; } if ((item instanceof HeaderItem) && !before) { - addAddTagMenuItems(null, addTagMenu, item, listener); + addAddTagMenuItems(null, addTagMenu, item, listener, null); } } private JMenu createOthersMenu(TreeItem item, AddTagActionListener listener) { JMenu othersMenu = new JMenu(AppStrings.translate("node.others")); othersMenu.setIcon(View.getIcon("folder16")); - addAddTagMenuItems(null, othersMenu, item, listener); + addAddTagMenuItems(null, othersMenu, item, listener, TagTreeModel.FOLDER_OTHERS); return othersMenu; } - private void addAddTagMenuItems(List allowedTagTypes, JMenu addTagMenu, TreeItem item, AddTagActionListener listener) { + private void addAddTagMenuItems(List allowedTagTypes, JMenu addTagMenu, TreeItem item, AddTagActionListener listener, String parentFolder) { if (allowedTagTypes == null) { boolean gfx = mainPanel.getCurrentSwf().gfx; @@ -1580,13 +1583,82 @@ public class TagTreeContextMenu extends JPopupMenu { TreeNodeType type = AbstractTagTree.getTagNodeTypeFromTagClass(cl); tagItem.setIcon(TagTree.getIconForType(type)); tagItem.addActionListener((ActionEvent ae) -> { - listener.call(ae, item, cl); + listener.call(ae, item, cl, null); }); addTagMenu.add(tagItem); } + + if (parentFolder == null) { + return; + } + switch (parentFolder) { + case TagTreeModel.FOLDER_SHAPES: + addTagMenu.addSeparator(); + JMenuItem createShapeItem = new JMenuItem(AppStrings.translate("tag.shape.create")); + createShapeItem.setIcon(View.getIcon("importshape16")); + createShapeItem.addActionListener((ActionEvent ae) -> { + listener.call(ae, item, DefineShape4Tag.class, TreeNodeType.SHAPE); + }); + addTagMenu.add(createShapeItem); + break; + case TagTreeModel.FOLDER_IMAGES: + addTagMenu.addSeparator(); + JMenuItem createImageItem = new JMenuItem(AppStrings.translate("tag.image.create")); + createImageItem.setIcon(View.getIcon("importimage16")); + createImageItem.addActionListener((ActionEvent ae) -> { + listener.call(ae, item, DefineBitsLossless2Tag.class, TreeNodeType.IMAGE); + }); + addTagMenu.add(createImageItem); + break; + case TagTreeModel.FOLDER_SPRITES: + addTagMenu.addSeparator(); + JMenuItem createSpriteItem = new JMenuItem(AppStrings.translate("tag.sprite.create")); + createSpriteItem.setIcon(View.getIcon("importsprite16")); + createSpriteItem.addActionListener((ActionEvent ae) -> { + listener.call(ae, item, DefineSpriteTag.class, TreeNodeType.SPRITE); + }); + addTagMenu.add(createSpriteItem); + break; + case TagTreeModel.FOLDER_MOVIES: + addTagMenu.addSeparator(); + JMenuItem createMovieItem = new JMenuItem(AppStrings.translate("tag.movie.create")); + createMovieItem.setIcon(View.getIcon("importmovie16")); + createMovieItem.addActionListener((ActionEvent ae) -> { + listener.call(ae, item, DefineVideoStreamTag.class, TreeNodeType.MOVIE); + }); + addTagMenu.add(createMovieItem); + break; + case TagTreeModel.FOLDER_SOUNDS: + addTagMenu.addSeparator(); + JMenuItem createSoundItem = new JMenuItem(AppStrings.translate("tag.sound.create")); + createSoundItem.setIcon(View.getIcon("importsound16")); + createSoundItem.addActionListener((ActionEvent ae) -> { + listener.call(ae, item, DefineSoundTag.class, TreeNodeType.SOUND); + }); + addTagMenu.add(createSoundItem); + break; + case TagTreeModel.FOLDER_FONTS: + addTagMenu.addSeparator(); + JMenuItem createFontItem = new JMenuItem(AppStrings.translate("tag.font.create")); + createFontItem.setIcon(View.getIcon("importfont16")); + createFontItem.addActionListener((ActionEvent ae) -> { + listener.call(ae, item, DefineFont3Tag.class, TreeNodeType.FONT); + }); + addTagMenu.add(createFontItem); + break; + case TagTreeModel.FOLDER_BINARY_DATA: + addTagMenu.addSeparator(); + JMenuItem createBinaryDataItem = new JMenuItem(AppStrings.translate("tag.binaryData.create")); + createBinaryDataItem.setIcon(View.getIcon("importbinarydata16")); + createBinaryDataItem.addActionListener((ActionEvent ae) -> { + listener.call(ae, item, DefineBinaryDataTag.class, TreeNodeType.BINARY_DATA); + }); + addTagMenu.add(createBinaryDataItem); + break; + } } - private void addTagInsideActionPerformed(ActionEvent evt, TreeItem item, Class cl) { + private void addTagInsideActionPerformed(ActionEvent evt, TreeItem item, Class cl, TreeNodeType createNodeType) { int id = -1; try { id = cl.getDeclaredField("ID").getInt(null); @@ -1629,13 +1701,14 @@ public class TagTreeContextMenu extends JPopupMenu { swf.updateCharacters(); mainPanel.refreshTree(swf); mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), t); + handleCreateFromFile(t, createNodeType); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) { logger.log(Level.SEVERE, null, ex); } } } - private void addTagBeforeActionPerformed(ActionEvent evt, TreeItem item, Class cl) { + private void addTagBeforeActionPerformed(ActionEvent evt, TreeItem item, Class cl, TreeNodeType createNodeType) { try { SWF swf = (SWF) item.getOpenable(); Tag t = (Tag) cl.getDeclaredConstructor(SWF.class).newInstance(new Object[]{swf}); @@ -1669,12 +1742,13 @@ public class TagTreeContextMenu extends JPopupMenu { swf.updateCharacters(); mainPanel.refreshTree(swf); mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), t); + handleCreateFromFile(t, createNodeType); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) { logger.log(Level.SEVERE, null, ex); } } - private void addTagAfterActionPerformed(ActionEvent evt, TreeItem item, Class cl) { + private void addTagAfterActionPerformed(ActionEvent evt, TreeItem item, Class cl, TreeNodeType createNodeType) { try { SWF swf = (SWF) item.getOpenable(); Tag t = (Tag) cl.getDeclaredConstructor(SWF.class).newInstance(new Object[]{swf}); @@ -1711,6 +1785,7 @@ public class TagTreeContextMenu extends JPopupMenu { swf.updateCharacters(); mainPanel.refreshTree(swf); mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), t); + handleCreateFromFile(t, createNodeType); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException ex) { logger.log(Level.SEVERE, null, ex); } @@ -3277,7 +3352,7 @@ public class TagTreeContextMenu extends JPopupMenu { } } - private void attachTagActionPerformed(ActionEvent evt, TreeItem item, Class cl) { + private void attachTagActionPerformed(ActionEvent evt, TreeItem item, Class cl, TreeNodeType createNodeType) { int id = -1; try { id = cl.getDeclaredField("ID").getInt(null); @@ -3726,4 +3801,31 @@ public class TagTreeContextMenu extends JPopupMenu { } } } + + private void handleCreateFromFile(Tag tag, TreeNodeType createNodeType) { + if (createNodeType == null) { + return; + } + boolean remove; + switch (createNodeType) { + case SPRITE: + remove = !mainPanel.replaceSpriteWithGif(tag); + break; + case SHAPE: + remove = !mainPanel.replaceNoFill(tag); + break; + case FONT: + remove = !mainPanel.fontEmbed(tag, true); + break; + default: + List sel = new ArrayList<>(); + sel.add(tag); + remove = !mainPanel.replace(sel, true); + break; + } + if (remove) { + tag.getTimelined().removeTag(tag); + mainPanel.refreshTree(); + } + } }