Changes of Revision 3

flowblade.changes Changed
x
 
1
@@ -1,4 +1,10 @@
2
 -------------------------------------------------------------------
3
+Sat Oct 22 17:36:13 UTC 2016 - avvissu@yandex.by
4
+
5
+- Update to 1.8:
6
+  * see /usr/share/docpackages/flowblade/RELEASE_NOTES
7
+
8
+-------------------------------------------------------------------
9
 Tue Jan 26 14:21:28 UTC 2016 - avvissu@yandex.ru
10
 
11
 - Update to 1.4:
12
flowblade.spec Changed
10
 
1
@@ -17,7 +17,7 @@
2
 
3
 %define prjname Flowblade
4
 Name:           flowblade
5
-Version:        1.4
6
+Version:        1.8
7
 Release:        0
8
 Summary:        Multitrack non-linear video editor
9
 License:        GPL-3.0
10
flowblade-1.4.tar.gz/.gitignore -> flowblade-1.8.tar.gz/.gitignore Changed
17
 
1
@@ -11,3 +11,15 @@
2
 *.po~
3
 *.py~
4
 *.pot~
5
+
6
+# All java related
7
+*.java
8
+*.class
9
+*.jar
10
+
11
+# Phantom 2D contents
12
+/flowblade-trunk/Flowblade/phantom2d
13
+/flowblade-trunk/Flowblade/phantom2d/res
14
+/flowblade-trunk/Flowblade/phantom2d/phantom_build
15
+/flowblade-trunk/Flowblade/phantom2d/src
16
+
17
flowblade-1.4.tar.gz/README.md -> flowblade-1.8.tar.gz/README.md Changed
68
 
1
@@ -1,7 +1,7 @@
2
 
3
 ![Flowblade](flowblade-trunk/Flowblade/res/img/header_text.png "Flowblade")
4
 
5
-**Release 1.4 is now avalable. See [release notes](./flowblade-trunk/docs/RELEASE_NOTES.md) for more info.**
6
+**NEW VERSION 1.8 AVAILABLE. Go to [release notes](./flowblade-trunk/docs/RELEASE_NOTES.md) to see what's new. Installing information available [here](./flowblade-trunk/docs/INSTALLING.md).**
7
 
8
 **Contents:**
9
   1. [Introduction](https://github.com/jliljebl/flowblade#introduction)
10
@@ -10,11 +10,11 @@
11
   1. [Installing Flowblade](https://github.com/jliljebl/flowblade#installing-flowblade)
12
   1. [Docs](https://github.com/jliljebl/flowblade#docs)
13
   1. [Screenshot](https://github.com/jliljebl/flowblade#screenshot)
14
-  1. [Forum and Contact](https://github.com/jliljebl/flowblade#forum-and-contact)
15
+  1. [Forum, Webpage and Contact](https://github.com/jliljebl/flowblade#forum-webpage-and-contact)
16
 
17
 # Introduction
18
 
19
-Flowblade Movie Editor is a **multitrack non-linear video editor** for Linux released under **GPL 3 license**.
20
+Flowblade is a **multitrack non-linear video editor** for Linux released under **GPL 3 license**.
21
 
22
 Flowblade is designed to provide a fast, precise and robust editing experience. Flowblade employs a film-style insert editing model as workflow. In insert editing clips are generally placed tightly after other clips when they are inserted on the timeline. Edits are fine tuned by trimming in and out points of clips or by cutting and deleting parts of clips.
23
 
24
@@ -56,9 +56,9 @@
25
         
26
 # Releases
27
 
28
-**Latest release:** Flowblade Movie Editor 1.4 was released on November 24, 2015.
29
+**Latest release:** Flowblade Movie Editor 1.8 was released on September 19, 2016.
30
 
31
-**Next release:** Flowblade Movie Editor 1.6 will be out on March 2016.
32
+**Next release:** Flowblade Movie Editor 1.10 will be out on December 2016.
33
 
34
 # Installing Flowblade
35
 
36
@@ -68,6 +68,8 @@
37
 
38
 [FAQ](./flowblade-trunk/docs/FAQ.md)
39
 
40
+[Known Issues](./flowblade-trunk/docs/KNOWN_ISSUES.md)
41
+
42
 [Roadmap](./flowblade-trunk/docs/ROADMAP.md)
43
 
44
 [Release notes](./flowblade-trunk/docs/RELEASE_NOTES.md)
45
@@ -80,12 +82,19 @@
46
 
47
 # Screenshot
48
 
49
-[Screenshot](./flowblade-trunk/docs/Screenshot-0-18.png) for version is 0.18 is available in the */docs* folder.
50
+[Screenshot 1.4 dark theme](./flowblade-trunk/docs/Screenshot-1-4-dark.png)
51
+
52
+[Screenshot 0.18 light theme](./flowblade-trunk/docs/Screenshot-0-18.png)
53
+
54
+These are in the repository */docs* folder.
55
+
56
+
57
+# Forum, Webpage and Contact
58
 
59
-# Forum and Contact
60
+[The project webpage is here](http://jliljebl.github.io/flowblade/). 
61
 
62
 For questions and discussion on Flowblade we have a [Google+ group] (https://plus.google.com/u/0/communities/103860400113389238474) available. There will be some updates on what is happening with the project too.
63
 
64
-Use the **Issues** tab on the right to give bug reports or to make feature requests.
65
+Use the **Issues** tab to give bug reports or to make feature requests.
66
 
67
 If needed, contact the project lead for additional information: janne.liljeblad@gmail.com
68
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/app.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/app.py Changed
201
 
1
@@ -24,9 +24,17 @@
2
 Handles application initialization, shutdown, opening projects, autosave and changing
3
 sequences.
4
 """
5
+try:
6
+    import pgi
7
+    pgi.install_as_gi()
8
+except ImportError:
9
+    pass
10
+    
11
+import gi
12
 
13
 from gi.repository import GObject
14
 from gi.repository import GLib
15
+gi.require_version('Gtk', '3.0')
16
 from gi.repository import Gtk
17
 from gi.repository import Gdk
18
 
19
@@ -52,6 +60,7 @@
20
 import editorpersistance
21
 import editorstate
22
 import editorwindow
23
+import gmic
24
 import gui
25
 import keyevents
26
 import medialog
27
@@ -63,6 +72,8 @@
28
 import mlttransitions
29
 import movemodes
30
 import persistance
31
+import phantomcompositor
32
+import positionbar
33
 import preferenceswindow
34
 import projectaction
35
 import projectdata
36
@@ -73,7 +84,10 @@
37
 import respaths
38
 import resync
39
 import sequence
40
+import snapping
41
+import titler
42
 import tlinewidgets
43
+import trimmodes
44
 import translations
45
 import undo
46
 import updater
47
@@ -96,14 +110,20 @@
48
 window_resize_id = -1
49
 window_state_id = -1
50
 
51
-logger = None
52
+_log_file = None
53
 
54
+assoc_file_path = None
55
+assoc_timeout_id = None
56
 
57
 def main(root_path):
58
     """
59
     Called at application start.
60
     Initializes application with a default project.
61
     """
62
+    # DEBUG: Direct output to log file if log file set
63
+    if _log_file != None:
64
+        log_print_output_to_file()
65
+    
66
     # Print OS, Python version and GTK+ version
67
     try:
68
         os_release_file = open("/etc/os-release","r")
69
@@ -126,6 +146,7 @@
70
 
71
     # passing -xdg as a flag will change the user_dir location with XDG_CONFIG_HOME
72
     # For full xdg-app support all the launch processes need to add this too, currently not impl.
73
+
74
     for arg in sys.argv:
75
         if arg.lower() == "-xdg":
76
             editorstate.use_xdg = True
77
@@ -145,7 +166,15 @@
78
         os.mkdir(user_dir + appconsts.AUDIO_LEVELS_DIR)
79
     if not os.path.exists(utils.get_hidden_screenshot_dir_path()):
80
         os.mkdir(utils.get_hidden_screenshot_dir_path())
81
-
82
+    if not os.path.exists(user_dir + appconsts.GMIC_DIR):
83
+        os.mkdir(user_dir + appconsts.GMIC_DIR)
84
+    """ This may be added back later
85
+    if not os.path.exists(user_dir + appconsts.NODE_COMPOSITORS_DIR):
86
+        os.mkdir(user_dir + appconsts.NODE_COMPOSITORS_DIR)
87
+    if not os.path.exists(user_dir + appconsts.NODE_COMPOSITORS_DIR + "/" + appconsts.PHANTOM_DISK_CACHE_DIR):
88
+        os.mkdir(user_dir + appconsts.NODE_COMPOSITORS_DIR + "/" + appconsts.PHANTOM_DISK_CACHE_DIR)
89
+    """
90
+        
91
     # Set paths.
92
     respaths.set_paths(root_path)
93
 
94
@@ -157,6 +186,7 @@
95
         editorstate.display_all_audio_levels = False
96
     editorpersistance.create_thumbs_folder_if_needed(user_dir)
97
     editorpersistance.create_rendered_clips_folder_if_needed(user_dir)
98
+
99
     editorpersistance.save()
100
 
101
     # Init translations module with translations data
102
@@ -164,11 +194,15 @@
103
     translations.load_filters_translations()
104
     mlttransitions.init_module()
105
 
106
+    # RHEL7/CentOS compatibility fix
107
+    if gtk_version == "3.8.8":
108
+        GObject.threads_init()
109
+
110
     # Init gtk threads
111
     Gdk.threads_init()
112
     Gdk.threads_enter()
113
 
114
-    # Request dark them if so desired
115
+    # Request dark theme if so desired
116
     if editorpersistance.prefs.dark_theme == True:
117
         Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", True)
118
 
119
@@ -215,28 +249,22 @@
120
     # Create list of available mlt profiles
121
     mltprofiles.load_profile_list()
122
     
123
-    # Launch association file if found in arguments
124
-    launch_file_path = get_assoc_file_path()
125
-    if launch_file_path != None:
126
-        try:
127
-            print "Launching assoc file:" +  launch_file_path
128
-            persistance.show_messages = False
129
-            editorstate.project = persistance.load_project(launch_file_path)
130
-            persistance.show_messages = True
131
-            check_crash = False
132
-        except:
133
-            editorstate.project = projectdata.get_default_project()
134
-            persistance.show_messages = True
135
-            check_crash = True
136
-    else:
137
-        # There is always a project open, so at startup we create a default project.
138
-        # Set default project as the project being edited.
139
-        editorstate.project = projectdata.get_default_project()
140
-        check_crash = True
141
+    # Save assoc file path if found in arguments
142
+    global assoc_file_path
143
+    assoc_file_path = get_assoc_file_path()
144
+        
145
+    # There is always a project open, so at startup we create a default project.
146
+    # Set default project as the project being edited.
147
+    editorstate.project = projectdata.get_default_project()
148
+    check_crash = True
149
 
150
     # Audiomonitoring being available needs to be known before GUI creation
151
     audiomonitoring.init(editorstate.project.profile)
152
 
153
+    # Check for tools
154
+    gmic.test_availablity()
155
+    #phantomcompositor.test_availablity()
156
+    
157
     # Create player object
158
     create_player()
159
 
160
@@ -264,7 +292,7 @@
161
     # Get existing autosave files
162
     autosave_files = get_autosave_files()
163
 
164
-    # Show splash
165
+    # Clear splash
166
     if ((editorpersistance.prefs.display_splash_screen == True) and len(autosave_files) == 0):
167
         global splash_timeout_id
168
         splash_timeout_id = GLib.timeout_add(2600, destroy_splash_screen)
169
@@ -285,9 +313,15 @@
170
         start_autosave()
171
 
172
     # We prefer to monkeypatch some callbacks into some modules, usually to
173
-    # maintain a simpler and non-circular import structure
174
+    # maintain a simpler and/or non-circular import structure
175
     monkeypatch_callbacks()
176
-    
177
+
178
+    if not(check_crash == True and len(autosave_files) > 0):
179
+        if assoc_file_path != None:
180
+            print "Launch assoc file:", assoc_file_path
181
+            global assoc_timeout_id
182
+            assoc_timeout_id = GObject.timeout_add(10, open_assoc_file)
183
+            
184
     # Launch gtk+ main loop
185
     Gtk.main()
186
 
187
@@ -312,6 +346,7 @@
188
     dnd.display_monitor_media_file = updater.set_and_display_monitor_media_file
189
     dnd.range_log_items_tline_drop = editevent.tline_range_item_drop
190
     dnd.range_log_items_log_drop = medialog.clips_drop
191
+    dnd.open_dropped_files = projectaction.open_file_names
192
 
193
     # Media log 
194
     medialog.do_multiple_clip_insert_func = editevent.do_multiple_clip_insert
195
@@ -319,6 +354,13 @@
196
     editevent.display_clip_menu_pop_up = clipmenuaction.display_clip_menu
197
     editevent.compositor_menu_item_activated = clipmenuaction._compositor_menu_item_activated
198
     
199
+    # Posionbar in gmic.py doesnot need trimmodes.py dependency and is avoided 
200
+    positionbar.trimmodes_set_no_edit_trim_mode = trimmodes.set_no_edit_trim_mode
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/appconsts.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/appconsts.py Changed
59
 
1
@@ -29,7 +29,7 @@
2
 VIDEO = 1
3
 AUDIO = 2
4
 IMAGE = 3
5
-RENDERED_VIDEO = 4 # not implemented
6
+RENDERED_VIDEO = 4 # not used
7
 PATTERN_PRODUCER = 5
8
 SYNC_AUDIO = 6
9
 FILE_DOES_NOT_EXIST = 7
10
@@ -68,7 +68,7 @@
11
 # Display heights for tracks.
12
 TRACK_HEIGHT_NORMAL = 50 # track height in canvas and column
13
 TRACK_HEIGHT_SMALL = 25 # track height in canvas and column
14
-TRACK_HEIGHT_SMALLEST = 25 # 20 # track height in canvas and column
15
+TRACK_HEIGHT_SMALLEST = 25 # maybe remove as it is no longer meaningful
16
 
17
 # Notebook widths
18
 NOTEBOOK_WIDTH = 600 # defines app min width with MONITOR_AREA_WIDTH
19
@@ -121,6 +121,11 @@
20
 MEDIA_LOG_INSERT = 0
21
 MEDIA_LOG_MARKS_SET = 1
22
 
23
+# Media log item sorting
24
+TIME_SORT = 0
25
+NAME_SORT = 1
26
+COMMENT_SORT = 2
27
+
28
 # Rendered clip types
29
 RENDERED_DISSOLVE = 0
30
 RENDERED_WIPE = 1
31
@@ -128,7 +133,7 @@
32
 RENDERED_FADE_IN = 3
33
 RENDERED_FADE_OUT = 4
34
 
35
-# Project proxt modes
36
+# Project proxy modes
37
 USE_ORIGINAL_MEDIA = 0
38
 USE_PROXY_MEDIA = 1
39
 CONVERTING_TO_USE_PROXY_MEDIA = 2
40
@@ -141,6 +146,9 @@
41
 # Hidden media folders
42
 THUMBNAILS_DIR = "thumbnails"
43
 RENDERED_CLIPS_DIR = "rendered_clips"
44
+GMIC_DIR = "gmic"
45
+NODE_COMPOSITORS_DIR = "node_compositors"
46
+PHANTOM_DISK_CACHE_DIR = "phantom_disk_cache"
47
 
48
 # Luma bands
49
 SHADOWS = 0
50
@@ -153,7 +161,7 @@
51
 MULTI_TRIM_REMOVE = 2
52
 MULTI_TRIM = 3
53
 
54
-# Jack options
55
+# Jack options (not used currently)
56
 JACK_ON_START_UP_NO = 0
57
 JACK_ON_START_UP_YES = 1
58
 
59
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/audiomonitoring.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/audiomonitoring.py Changed
24
 
1
@@ -20,6 +20,14 @@
2
 """
3
 Module handles initializing and displaying audiomonitor tool.
4
 """
5
+try:
6
+    import pgi
7
+    pgi.install_as_gi()
8
+except ImportError:
9
+    pass
10
+    
11
+import gi
12
+
13
 import cairo
14
 import mlt
15
 import time
16
@@ -28,6 +36,7 @@
17
 from gi.repository import GLib
18
 from gi.repository import Gdk
19
 from gi.repository import Pango
20
+gi.require_version('PangoCairo', '1.0')
21
 from gi.repository import PangoCairo
22
 
23
 import appconsts
24
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/audiowaveformrenderer.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/audiowaveformrenderer.py Changed
19
 
1
@@ -88,7 +88,7 @@
2
         return None
3
     
4
 # ------------------------------------------------- launching render
5
-def render_queued():
6
+def launch_queued_renders():
7
     # Render files that were not found when timeline was displayed
8
     global _queued_waveform_renders
9
     if len(_queued_waveform_renders) == 0:
10
@@ -133,7 +133,7 @@
11
         self.rendered_media = rendered_media
12
         self.profile_desc = profile_desc
13
 
14
-    def run(self):      
15
+    def run(self):
16
         # Launch render process and wait for it to end
17
         FLOG = open(utils.get_hidden_user_dir_path() + "log_audio_levels_render", 'w')
18
         process = subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladeaudiorender", \
19
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/clipeffectseditor.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/clipeffectseditor.py Changed
9
 
1
@@ -490,5 +490,7 @@
2
         kf_widget.display_tline_frame(frame)
3
 
4
 def update_kfeditors_positions():
5
+    if clip == None:
6
+        return
7
     for kf_widget in keyframe_editor_widgets:
8
         kf_widget.update_clip_pos()
9
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/clipmenuaction.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/clipmenuaction.py Changed
87
 
1
@@ -22,13 +22,16 @@
2
 This module handles actions initiated from clip and compositor popup menus.
3
 """
4
 
5
+from PIL import Image
6
+
7
+from gi.repository import Gtk
8
+
9
 import audiowaveform
10
 import appconsts
11
 import clipeffectseditor
12
 import compositeeditor
13
 import dialogs
14
 import dialogutils
15
-from gi.repository import Gtk
16
 import gui
17
 import guicomponents
18
 import edit
19
@@ -39,6 +42,7 @@
20
 import movemodes
21
 import syncsplitevent
22
 import tlinewidgets
23
+import tlineaction
24
 import updater
25
 import utils
26
 
27
@@ -87,23 +91,8 @@
28
         action = edit.delete_compositor_action(data)
29
         action.do_edit()
30
     elif action_id == "sync with origin":
31
-        track = current_sequence().tracks[compositor.transition.b_track] # b_track is source track where origin clip is
32
-        origin_clip = None
33
-        for clip in track.clips:
34
-            if clip.id == compositor.origin_clip_id:
35
-                origin_clip = clip
36
-        if origin_clip == None:
37
-            dialogutils.info_message(_("Origin clip not found!"), 
38
-                                 _("Clip used to create this Compositor has been removed\nor moved to different track."), 
39
-                                 gui.editor_window.window)
40
-            return
41
-        clip_index = track.clips.index(origin_clip)
42
-        clip_start = track.clip_start(clip_index)
43
-        clip_end = clip_start + origin_clip.clip_out - origin_clip.clip_in
44
-        data = {"compositor":compositor,"clip_in":clip_start,"clip_out":clip_end}
45
-        action = edit.move_compositor_action(data)
46
-        action.do_edit()
47
-
48
+        tlineaction.sync_compositor(compositor)
49
+        
50
 def _open_clip_in_effects_editor(data):
51
     updater.open_clip_in_effects_editor(data)
52
     
53
@@ -118,21 +107,30 @@
54
 
55
 def _show_clip_info(data):
56
     clip, track, item_id, x = data
57
-    
58
+
59
     width = clip.get("width")
60
     height = clip.get("height")
61
+    if clip.media_type == appconsts.IMAGE:
62
+        graphic_img = Image.open(clip.path)
63
+        width, height = graphic_img.size
64
     size = str(width) + " x " + str(height)
65
     l_frames = clip.clip_out - clip.clip_in + 1 # +1 out inclusive
66
     length = utils.get_tc_string(l_frames)
67
+    mark_in = utils.get_tc_string(clip.clip_in)
68
+    mark_out = utils.get_tc_string(clip.clip_out + 1) # +1 out inclusive
69
 
70
     video_index = clip.get_int("video_index")
71
     audio_index = clip.get_int("audio_index")
72
     long_video_property = "meta.media." + str(video_index) + ".codec.long_name"
73
     long_audio_property = "meta.media." + str(audio_index) + ".codec.long_name"
74
     vcodec = clip.get(str(long_video_property))
75
-    acodec = clip.get(str(long_audio_property))
76
+    acodec = clip.get(str(long_audio_property))    
77
+    if vcodec == None:
78
+        vcodec = _("N/A")
79
+    if acodec == None:
80
+        acodec = _("N/A")
81
 
82
-    dialogs.clip_properties_dialog((length, size, clip.path, vcodec, acodec))
83
+    dialogs.clip_properties_dialog((mark_in, mark_out, length, size, clip.path, vcodec, acodec))
84
 
85
 def _rename_clip(data):
86
     clip, track, item_id, x = data
87
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/compositeeditor.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/compositeeditor.py Changed
9
 
1
@@ -95,6 +95,7 @@
2
 
3
     set_enabled(True)
4
     _display_compositor_edit_box()
5
+    # ????? this is not used
6
     if editorpersistance.prefs.default_layout == True:
7
         gui.middle_notebook.set_current_page(3)
8
     else:
9
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/dialogs.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/dialogs.py Changed
201
 
1
@@ -19,7 +19,7 @@
2
 """
3
 
4
 """
5
-Module builds dialog windows. User input is handled at 
6
+Module builds dialog windows. User input is handled at
7
 callsites which provide callback methods for response signals.
8
 """
9
 
10
@@ -54,19 +54,19 @@
11
                         Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
12
                         (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
13
                          _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
14
-                        
15
+
16
     out_profile_combo = Gtk.ComboBoxText()
17
     profiles = mltprofiles.get_profiles()
18
     for profile in profiles:
19
         out_profile_combo.append_text(profile[0])
20
 
21
-    out_profile_combo.set_active(default_profile_index)    
22
+    out_profile_combo.set_active(default_profile_index)
23
     profile_select = panels.get_two_column_box(Gtk.Label(label=_("Project profile:")),
24
                                                out_profile_combo,
25
                                                250)
26
 
27
     profile_info_panel = guicomponents.get_profile_info_box(default_profile, False)
28
-    profile_info_box = Gtk.VBox() 
29
+    profile_info_box = Gtk.VBox()
30
     profile_info_box.add(profile_info_panel)
31
     profiles_vbox = guiutils.get_vbox([profile_select,profile_info_box], False)
32
     profiles_frame = panels.get_named_frame(_("Profile"), profiles_vbox)
33
@@ -84,24 +84,139 @@
34
     dialogutils.set_outer_margins(dialog.vbox)
35
     dialog.vbox.pack_start(alignment, True, True, 0)
36
     _default_behaviour(dialog)
37
-    dialog.connect('response', callback, out_profile_combo, tracks_combo, 
38
-                   tracks_combo_values_list)#, project_type_combo, 
39
-                   #project_folder, compact_name_entry)
40
+    dialog.connect('response', callback, out_profile_combo, tracks_combo,
41
+                   tracks_combo_values_list)
42
+                   
43
     out_profile_combo.connect('changed', lambda w: _new_project_profile_changed(w, profile_info_box))
44
     dialog.show_all()
45
-    
46
+
47
 def _new_project_profile_changed(combo_box, profile_info_box):
48
     profile = mltprofiles.get_profile_for_index(combo_box.get_active())
49
-    
50
+
51
     info_box_children = profile_info_box.get_children()
52
     for child in info_box_children:
53
         profile_info_box.remove(child)
54
-    
55
+
56
     info_panel = guicomponents.get_profile_info_box(profile, True)
57
     profile_info_box.add(info_panel)
58
     profile_info_box.show_all()
59
     info_panel.show()
60
 
61
+def change_profile_project_dialog(project, callback):
62
+    project_name = project.name.rstrip(".flb")
63
+    default_profile_index = mltprofiles.get_index_for_name(project.profile.description())
64
+    default_profile = mltprofiles.get_default_profile()
65
+
66
+    dialog = Gtk.Dialog(_("Change Project Profile"), gui.editor_window.window,
67
+                        Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
68
+                        (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
69
+                         _("Save With Changed Profile").encode('utf-8'), Gtk.ResponseType.ACCEPT))
70
+
71
+    info_label = guiutils.bold_label(_("Project Profile can only changed by saving a version\nwith different profile."))
72
+
73
+    out_profile_combo = Gtk.ComboBoxText()
74
+    profiles = mltprofiles.get_profiles()
75
+    for profile in profiles:
76
+        out_profile_combo.append_text(profile[0])
77
+
78
+    out_profile_combo.set_active(default_profile_index)
79
+    profile_select = panels.get_two_column_box(Gtk.Label(label=_("Project profile:")),
80
+                                               out_profile_combo,
81
+                                               250)
82
+
83
+    profile_info_panel = guicomponents.get_profile_info_box(default_profile, False)
84
+    profile_info_box = Gtk.VBox()
85
+    profile_info_box.add(profile_info_panel)
86
+    profiles_vbox = guiutils.get_vbox([profile_select,profile_info_box], False)
87
+    profiles_frame = panels.get_named_frame(_("New Profile"), profiles_vbox)
88
+
89
+    out_folder = Gtk.FileChooserButton(_("Select Folder"))
90
+    out_folder.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
91
+    out_folder.set_current_folder(os.path.expanduser("~") + "/")
92
+    out_folder.set_local_only(True)
93
+    out_folder_row = panels.get_two_column_box(Gtk.Label(label=_("Folder:")), out_folder,  250)
94
+
95
+    project_name_entry = Gtk.Entry()
96
+    project_name_entry.set_text(project_name + "_NEW_PROFILE.flb")
97
+    extension_label = Gtk.Label()
98
+
99
+    name_box = Gtk.HBox(False, 8)
100
+    name_box.pack_start(project_name_entry, True, True, 0)
101
+
102
+    movie_name_row =  panels.get_two_column_box(Gtk.Label(label=_("Project Name:")), name_box,  250)
103
+
104
+    new_file_vbox = guiutils.get_vbox([out_folder_row, movie_name_row], False)
105
+
106
+    new_file_frame = panels.get_named_frame(_("New Project File"), new_file_vbox)
107
+
108
+    vbox = guiutils.get_vbox([info_label, guiutils.pad_label(2, 24), profiles_frame, new_file_frame], False)
109
+
110
+    alignment = dialogutils.get_default_alignment(vbox)
111
+    dialogutils.set_outer_margins(dialog.vbox)
112
+    dialog.vbox.pack_start(alignment, True, True, 0)
113
+    _default_behaviour(dialog)
114
+    dialog.connect('response', callback, out_profile_combo, out_folder, project_name_entry)#, project_type_combo,
115
+                   #project_folder, compact_name_entry)
116
+    out_profile_combo.connect('changed', lambda w: _new_project_profile_changed(w, profile_info_box))
117
+    dialog.show_all()
118
+
119
+def change_profile_project_to_match_media_dialog(project, media_file, callback):
120
+    project_name = project.name.rstrip(".flb")
121
+    default_profile_index = mltprofiles.get_index_for_name(project.profile.description())
122
+    default_profile = mltprofiles.get_default_profile()
123
+
124
+    dialog = Gtk.Dialog(_("Change Project Profile"), gui.editor_window.window,
125
+                        Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
126
+                        (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
127
+                         _("Save With Changed Profile").encode('utf-8'), Gtk.ResponseType.ACCEPT))
128
+
129
+    info_label = guiutils.bold_label(_("Project Profile can only changed by saving a version\nwith different profile."))
130
+
131
+    match_profile_index = mltprofiles.get_closest_matching_profile_index(media_file.info)
132
+    match_profile_name =  mltprofiles.get_profile_name_for_index(match_profile_index)
133
+    project_profile_name = project.profile.description()
134
+
135
+    row1 = guiutils.get_two_column_box(guiutils.bold_label(_("File:")), Gtk.Label(label=media_file.name), 120)
136
+    row2 = guiutils.get_two_column_box(guiutils.bold_label(_("File Best Match Profile:")), Gtk.Label(label=match_profile_name), 120)
137
+    row3 = guiutils.get_two_column_box(guiutils.bold_label(_("Project Current Profile:")), Gtk.Label(label=project_profile_name), 120)
138
+
139
+    text_panel = Gtk.VBox(False, 2)
140
+    text_panel.pack_start(row1, False, False, 0)
141
+    text_panel.pack_start(row2, False, False, 0)
142
+    text_panel.pack_start(row3, False, False, 0)
143
+
144
+    out_folder = Gtk.FileChooserButton(_("Select Folder"))
145
+    out_folder.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
146
+    out_folder.set_current_folder(os.path.expanduser("~") + "/")
147
+    out_folder.set_local_only(True)
148
+    out_folder_row = panels.get_two_column_box(Gtk.Label(label=_("Folder:")), out_folder,  250)
149
+
150
+    project_name_entry = Gtk.Entry()
151
+    project_name_entry.set_text(project_name + "_NEW_PROFILE.flb")
152
+    extension_label = Gtk.Label()
153
+
154
+    name_box = Gtk.HBox(False, 8)
155
+    name_box.pack_start(project_name_entry, True, True, 0)
156
+
157
+    movie_name_row =  panels.get_two_column_box(Gtk.Label(label=_("Project Name:")), name_box,  250)
158
+
159
+    new_file_vbox = guiutils.get_vbox([out_folder_row, movie_name_row], False)
160
+
161
+    new_file_frame = panels.get_named_frame(_("New Project File"), new_file_vbox)
162
+
163
+    save_profile_info =  guiutils.bold_label(_("Project will be saved with profile: ") + match_profile_name)
164
+
165
+    vbox = guiutils.get_vbox([info_label, guiutils.pad_label(2, 24), text_panel, \
166
+                              guiutils.pad_label(2, 24), save_profile_info, guiutils.pad_label(2, 24), \
167
+                              new_file_frame], False)
168
+
169
+    alignment = dialogutils.get_default_alignment(vbox)
170
+    dialogutils.set_outer_margins(dialog.vbox)
171
+    dialog.vbox.pack_start(alignment, True, True, 0)
172
+    _default_behaviour(dialog)
173
+    dialog.connect('response', callback, match_profile_index, out_folder, project_name_entry)
174
+    dialog.show_all()
175
+
176
 def save_backup_snapshot(name, callback):
177
     dialog = Gtk.Dialog(_("Save Project Backup Snapshot"),  gui.editor_window.window,
178
                         Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
179
@@ -111,23 +226,23 @@
180
     project_folder = Gtk.FileChooserButton(_("Select Snapshot Project Folder"))
181
     project_folder.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
182
     project_folder.set_current_folder(os.path.expanduser("~") + "/")
183
-    
184
+
185
     project_folder_label = Gtk.Label(label=_("Snapshot Folder:"))
186
-    
187
+
188
     project_folder_row = guiutils.get_two_column_box(project_folder_label, project_folder, 250)
189
 
190
     compact_name_entry = Gtk.Entry.new()
191
     compact_name_entry.set_width_chars(30)
192
     compact_name_entry.set_text(name)
193
-    
194
+
195
     compact_name_label = Gtk.Label(label=_("Project File Name:"))
196
-    
197
+
198
     compact_name_entry_row = guiutils.get_two_column_box(compact_name_label, compact_name_entry, 250)
199
-    
200
+
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/dialogutils.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/dialogutils.py Changed
59
 
1
@@ -65,6 +65,19 @@
2
     dialog.set_resizable(False)
3
     dialog.connect('response', callback)
4
     dialog.show_all()
5
+
6
+def warning_message_with_panels(primary_txt, secondary_txt, parent_window, is_info, callback, panels):
7
+    content = get_warning_message_dialog_panel(primary_txt, secondary_txt, is_info, None, panels)
8
+    dialog = Gtk.Dialog("",
9
+                        parent_window,
10
+                        Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
11
+                        ( _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
12
+    alignment = get_default_alignment(content)
13
+    dialog.vbox.pack_start(alignment, True, True, 0)
14
+    set_outer_margins(dialog.vbox)
15
+    dialog.set_resizable(False)
16
+    dialog.connect('response', callback)
17
+    dialog.show_all()
18
     
19
 def warning_confirmation(callback, primary_txt, secondary_txt, parent_window, data=None, is_info=False):
20
     content = get_warning_message_dialog_panel(primary_txt, secondary_txt, is_info)
21
@@ -85,8 +98,8 @@
22
 
23
     dialog.show_all()
24
 
25
-def get_warning_message_dialog_panel(primary_txt, secondary_txt, is_info=False, alternative_icon=None):
26
-    
27
+def get_warning_message_dialog_panel(primary_txt, secondary_txt, is_info=False, alternative_icon=None, panels=None):
28
+
29
     if is_info == True:
30
         icon = Gtk.STOCK_DIALOG_INFO
31
     else:
32
@@ -118,6 +131,9 @@
33
     text_box.pack_start(pbox, False, False, 0)
34
     text_box.pack_start(texts_pad, False, False, 0)
35
     text_box.pack_start(sbox, False, False, 0)
36
+    if panels != None:
37
+        for panel in panels:
38
+            text_box.pack_start(panel, False, False, 0)
39
     text_box.pack_start(Gtk.Label(), True, True, 0)
40
 
41
     hbox = Gtk.HBox(False, 12)
42
@@ -157,14 +173,14 @@
43
     return (dialog, entry)
44
 
45
 def get_default_alignment(panel):
46
-    alignment = Gtk.Frame.new(None)
47
+    alignment = Gtk.Frame.new("") #Gtk.Frame.new(None)
48
     alignment.add(panel)
49
     alignment.set_shadow_type(Gtk.ShadowType.NONE)
50
     guiutils.set_margins(alignment, 12, 24, 12, 18)
51
     return alignment
52
 
53
 def get_alignment2(panel):
54
-    alignment = Gtk.Frame.new(None)
55
+    alignment = Gtk.Frame.new("") #Gtk.Frame.new(None)
56
     alignment.add(panel)
57
     alignment.set_shadow_type(Gtk.ShadowType.NONE)
58
     guiutils.set_margins(alignment, 6, 24, 12, 12)
59
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/dnd.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/dnd.py Changed
87
 
1
@@ -25,9 +25,13 @@
2
 from gi.repository import Gtk
3
 from gi.repository import Gdk
4
 from gi.repository import GdkPixbuf
5
+from gi.repository import GLib
6
+
7
+import os
8
 
9
 import editorstate
10
 import gui
11
+import utils
12
 import respaths
13
 
14
 # Source identifiers
15
@@ -45,6 +49,9 @@
16
 CLIPS_DND_TARGET = Gtk.TargetEntry.new('clip', Gtk.TargetFlags.SAME_APP, 0)
17
 RANGE_DND_TARGET = Gtk.TargetEntry.new('range', Gtk.TargetFlags.SAME_APP, 0)
18
 
19
+URI_DND_TARGET = Gtk.TargetEntry.new('text/uri-list', 0, 0)
20
+
21
+
22
 # These used to hold data needed on drag drop instead of the API provided GtkSelectionData.
23
 drag_data = None 
24
 drag_source = None
25
@@ -58,7 +65,7 @@
26
 display_monitor_media_file = None
27
 range_log_items_tline_drop = None
28
 range_log_items_log_drop = None
29
-
30
+open_dropped_files = None
31
 
32
 def init():
33
     global clip_icon, empty_icon
34
@@ -71,10 +78,11 @@
35
     widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
36
                            [MEDIA_FILES_DND_TARGET], 
37
                            Gdk.DragAction.COPY)
38
-    #widget.connect_after('drag_begin', _media_files_drag_begin)
39
     widget.connect("drag_data_get", _media_files_drag_data_get)
40
     widget.drag_source_set_icon_pixbuf(clip_icon)
41
-
42
+    
43
+    connect_media_drop_widget(widget)
44
+    
45
 def connect_media_files_object_cairo_widget(widget):
46
     widget.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
47
                            [MEDIA_FILES_DND_TARGET], 
48
@@ -82,6 +90,13 @@
49
     widget.connect("drag_data_get", _media_files_drag_data_get)
50
     widget.drag_source_set_icon_pixbuf(clip_icon)
51
 
52
+    connect_media_drop_widget(widget)
53
+
54
+def connect_media_drop_widget(widget):
55
+    widget.drag_dest_set(Gtk.DestDefaults.ALL, [URI_DND_TARGET], Gdk.DragAction.COPY)
56
+    widget.drag_dest_add_uri_targets()
57
+    widget.connect("drag_data_received", _media_files_drag_received)
58
+    
59
 def connect_bin_tree_view(treeview, move_files_to_bin_func):
60
     treeview.enable_model_drag_dest([MEDIA_FILES_DND_TARGET],
61
                                     Gdk.DragAction.DEFAULT)
62
@@ -142,6 +157,24 @@
63
 def _media_files_drag_data_get(widget, context, selection, target_id, timestamp):
64
     _save_media_panel_selection()
65
 
66
+def _media_files_drag_received(widget, context, x, y, data, info, timestamp):
67
+    uris = data.get_uris()
68
+    files = []
69
+    for uri in uris:
70
+        try:
71
+            uri_tuple = GLib.filename_from_uri(uri)
72
+        except:
73
+            continue
74
+        uri, unused = uri_tuple
75
+        if os.path.exists(uri) == True:
76
+            if utils.is_media_file(uri) == True:
77
+                files.append(uri)
78
+
79
+    if len(files) == 0:
80
+        return
81
+
82
+    open_dropped_files(files)
83
+    
84
 def _range_log_drag_data_get(treeview, context, selection, target_id, timestamp):
85
     _save_treeview_selection(treeview)
86
     global drag_source
87
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/edit.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/edit.py Changed
10
 
1
@@ -1436,7 +1436,7 @@
2
     self.compositor.set_in_and_out(self.in_frame, self.out_frame)
3
     self.compositor.origin_clip_id = self.origin_clip_id
4
 
5
-    # Compositors are recreated continually in sequnece.restack_compositors() and cannot be identified for undo/redo using object identity 
6
+    # Compositors are recreated continually in sequence.restack_compositors() and cannot be identified for undo/redo using object identity 
7
     # so these ids must be  preserved for all succesive versions of a compositor
8
     if self.first_do == True:
9
         self.destroy_id = self.compositor.destroy_id
10
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/editorpersistance.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/editorpersistance.py Changed
49
 
1
@@ -72,7 +72,19 @@
2
         write_file = file(recents_file_path, "wb")
3
         pickle.dump(recent_projects, write_file)
4
 
5
-    # version of program may have different prefs objects and 
6
+    # Remove non-existing projects from recents list
7
+    remove_list = []
8
+    for proj_path in recent_projects.projects:
9
+        if os.path.isfile(proj_path) == False:
10
+            remove_list.append(proj_path)
11
+
12
+    if len(remove_list) > 0:
13
+        for proj_path in remove_list:
14
+            recent_projects.projects.remove(proj_path)
15
+        write_file = file(recents_file_path, "wb")
16
+        pickle.dump(recent_projects, write_file)
17
+        
18
+    # Versions of program may have different prefs objects and 
19
     # we may need to to update prefs on disk if user has e.g.
20
     # installed later version of Flowblade
21
     current_prefs = EditorPreferences()
22
@@ -162,8 +174,9 @@
23
 
24
     default_profile_combo, open_in_last_opened_check, open_in_last_rendered_check, undo_max_spin, load_order_combo = gen_opts_widgets
25
     
26
+    # Jul-2016 - SvdB - Added play_pause_button
27
     auto_play_in_clip_monitor_check, auto_center_check, grfx_insert_length_spin, \
28
-    trim_exit_click, trim_quick_enter, remember_clip_frame, overwrite_clip_drop, cover_delete = edit_prefs_widgets
29
+    trim_exit_click, trim_quick_enter, remember_clip_frame, overwrite_clip_drop, cover_delete, play_pause_button = edit_prefs_widgets
30
     
31
     use_english, disp_splash, buttons_style, dark_theme, theme_combo, audio_levels_combo = view_prefs_widgets
32
 
33
@@ -182,6 +195,8 @@
34
     prefs.remember_monitor_clip_frame = remember_clip_frame.get_active()
35
     prefs.overwrite_clip_drop = (overwrite_clip_drop.get_active() == 0)
36
     prefs.trans_cover_delete = cover_delete.get_active()
37
+    # Jul-2016 - SvdB - For play/pause button
38
+    prefs.play_pause = play_pause_button.get_active()
39
     
40
     prefs.use_english_always = use_english.get_active()
41
     prefs.display_splash_screen = disp_splash.get_active()
42
@@ -257,3 +272,6 @@
43
         self.display_all_audio_levels = True
44
         self.overwrite_clip_drop = True
45
         self.trans_cover_delete = True
46
+        # Jul-2016 - SvdB - For play/pause button
47
+        self.play_pause = False
48
+
49
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/editorstate.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/editorstate.py Changed
62
 
1
@@ -19,13 +19,14 @@
2
 """
3
 
4
 """
5
-Module holds current editor state.
6
+Module holds current global editor state.
7
 
8
 Accessor methods are there mainly to improve code readability elsewhere.
9
 
10
 We're using BIG_METHOD_NAMES() for state objects. This is a bit unusual
11
 but looks good when reading code.
12
 """
13
+
14
 import appconsts
15
 
16
 # Edit modes
17
@@ -42,6 +43,7 @@
18
 MULTI_MOVE = 10
19
 CLIP_END_DRAG = 11
20
 
21
+
22
 # Project being edited
23
 project = None
24
 
25
@@ -99,6 +101,7 @@
26
 
27
 # Audio levels display mode, False means that audio levels are displayed on request
28
 display_all_audio_levels = True
29
+display_clip_media_thumbnails = True
30
 
31
 # Flag for window being in fullscreen mode
32
 fullscreen = False
33
@@ -151,21 +154,16 @@
34
     return _timeline_displayed
35
 
36
 def mlt_version_is_equal_or_greater(test_version):
37
-    runtime_ver = _get_mlt_ver_num(mlt_version)
38
-    t_ver = _get_mlt_ver_num(test_version)
39
-
40
-    if runtime_ver >= t_ver:
41
-        return True
42
+    runtime_ver = mlt_version.split(".")
43
+    test_ver = test_version.split(".")
44
+    
45
+    if runtime_ver[0] >= test_ver[0]:
46
+        if  runtime_ver[1] >= test_ver[1]:
47
+            if  runtime_ver[2] >= test_ver[2]:
48
+                return True
49
     
50
     return False
51
 
52
-def _get_mlt_ver_num(ver):
53
-    parts = ver.split(".")
54
-    p_str = parts[0] + parts[1] + parts[2]
55
-    p_str =  p_str.lstrip("0")
56
-
57
-    return int(p_str)
58
-
59
 def set_copy_paste_objects(objs):
60
     global _copy_paste_objects
61
     _copy_paste_objects = objs
62
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/editorwindow.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/editorwindow.py Changed
201
 
1
@@ -42,6 +42,7 @@
2
 import editorstate
3
 import exporting
4
 import glassbuttons
5
+import gmic
6
 import gui
7
 import guicomponents
8
 import guiutils
9
@@ -55,6 +56,7 @@
10
 import rendergui
11
 import panels
12
 import patternproducer
13
+import phantomcompositor
14
 from positionbar import PositionBar
15
 import preferenceswindow
16
 import projectaction
17
@@ -131,7 +133,7 @@
18
         self.window.connect("delete-event", lambda w, e:app.shutdown())
19
 
20
         # Player consumer has to be stopped and started when window resized
21
-        self.window.connect("window-state-event", lambda w, e:updater.refresh_player())
22
+        self.window.connect("window-state-event", lambda w, e:updater.refresh_player(e))
23
 
24
         # Build menubar
25
         # Menubar build resources
26
@@ -145,7 +147,7 @@
27
             ('SaveSnapshot', None, _('Save Backup Snapshot...'), None, None, lambda a:projectaction.save_backup_snapshot()),
28
             ('ExportMenu', None, _('Export')),
29
             ('ExportMeltXML', None, _('MLT XML'), None, None, lambda a:exporting.MELT_XML_export()),
30
-            ('ExportEDL', None, _('EDL CMX 3600'), None, None, lambda a:exporting.EDL_export()),
31
+            ('ExportEDL', None, _('EDL'), None, None, lambda a:exporting.EDL_export()),
32
             ('ExportScreenshot', None, _('Current Frame'), None, None, lambda a:exporting.screenshot_export()),
33
             ('Close', None, _('_Close'), None, None, lambda a:projectaction.close_project()),
34
             ('Quit', None, _('_Quit'), '<control>Q', None, lambda a:app.shutdown()),
35
@@ -168,6 +170,7 @@
36
             ('AddTransition', None, _('Add Single Track Transition'), None, None, lambda a:tlineaction.add_transition_menu_item_selected()),
37
             ('AddFade', None, _('Add Single Track Fade'), None, None, lambda a:tlineaction.add_fade_menu_item_selected()),
38
             ('ClearFilters', None, _('Clear Filters'), None, None, lambda a:clipmenuaction.clear_filters()),
39
+            ('SyncCompositors', None, _('Sync All Compositors'), None, None, lambda a:tlineaction.sync_all_compositors()),
40
             ('ChangeSequenceTracks', None, _('Change Sequence Tracks Count...'), None, None, lambda a:projectaction.change_sequence_track_count()),
41
             ('Watermark', None, _('Watermark...'), None, None, lambda a:menuactions.edit_watermark()),
42
             ('ProfilesManager', None, _('Profiles Manager'), None, None, lambda a:menuactions.profiles_manager()),
43
@@ -187,8 +190,8 @@
44
             ('RecreateMediaIcons', None, _('Recreate Media Icons...'), None, None, lambda a:menuactions.recreate_media_file_icons()),
45
             ('RemoveUnusedMedia', None, _('Remove Unused Media...'), None, None, lambda a:projectaction.remove_unused_media()),
46
             ('JackAudio', None, _("JACK Audio..."), None, None, lambda a: menuactions.jack_output_managing()),
47
+            ('ChangeProfile', None, _("Change Project Profile..."), None, None, lambda a: projectaction.change_project_profile()),
48
             ('ProxyManager', None, _('Proxy Manager'), None, None, lambda a:proxyediting.show_proxy_manager_dialog()),
49
-            ('ProjectType', None, _("Change Project Type..."), None, None,  lambda a:projectaction.change_project_type()),
50
             ('ProjectInfo', None, _('Project Info'), None, None, lambda a:menuactions.show_project_info()),
51
             ('RenderMenu', None, _('Render')),
52
             ('AddToQueue', None, _('Add To Batch Render Queue...'), None, None, lambda a:projectaction.add_to_render_queue()),
53
@@ -197,6 +200,8 @@
54
             ('ToolsMenu', None, _('Tools')),
55
             ('Titler', None, _('Titler'), None, None, lambda a:titler.show_titler()),
56
             ('AudioMix', None, _('Audio Mixer'), None, None, lambda a:audiomonitoring.show_audio_monitor()),
57
+            ('GMIC', None, _("G'MIC Effects"), None, None, lambda a:gmic.launch_gmic()),
58
+            ('Phantom2D', None, _("Phantom2D"), None, None, lambda a: phantomcompositor.launch_phantom()),
59
             ('MediaLink', None, _('Media Relinker'), None, None, lambda a:medialinker.display_linker()),
60
             ('HelpMenu', None, _('_Help')),
61
             ('QuickReference', None, _('Contents'), None, None, lambda a:menuactions.quick_reference()),
62
@@ -223,6 +228,7 @@
63
                     <separator/>
64
                     <menu action='ExportMenu'>
65
                         <menuitem action='ExportMeltXML'/>
66
+                        <menuitem action='ExportEDL'/>
67
                         <menuitem action='ExportScreenshot'/>
68
                     </menu>
69
                     <separator/>
70
@@ -249,6 +255,7 @@
71
                     <menuitem action='SpliceOutClip'/>
72
                     <menuitem action='DeleteClip'/>
73
                     <menuitem action='ResyncSelected'/>
74
+                    <menuitem action='SyncCompositors'/>
75
                     <menuitem action='ClearFilters'/>
76
                     <separator/>
77
                     <menuitem action='AddTransition'/>
78
@@ -280,6 +287,8 @@
79
                     <menuitem action='RecreateMediaIcons'/>
80
                     <menuitem action='RemoveUnusedMedia'/>
81
                     <separator/>
82
+                    <menuitem action='ChangeProfile'/>
83
+                    <separator/>
84
                     <menuitem action='ProxyManager'/>
85
                 </menu>
86
                 <menu action='RenderMenu'>
87
@@ -289,9 +298,11 @@
88
                     <menuitem action='Render'/>
89
                 </menu>
90
                 <menu action='ToolsMenu'>
91
-                    <menuitem action='Titler'/>
92
                     <menuitem action='AudioMix'/>
93
                     <separator/>
94
+                    <menuitem action='Titler'/>
95
+                    <menuitem action='GMIC'/>
96
+                    <separator/>
97
                     <menuitem action='MediaLink'/>
98
                 </menu>
99
                 <menu action='HelpMenu'>
100
@@ -405,7 +416,7 @@
101
         compositors_hbox.pack_start(compositor_clip_panel, False, False, 0)
102
         compositors_hbox.pack_start(compositor_editor_panel, True, True, 0)
103
 
104
-        self.compositors_panel = compositors_hbox
105
+        self.compositors_panel = guiutils.set_margins(compositors_hbox, 2, 2, 2, 2) 
106
 
107
         # Render panel
108
         try:
109
@@ -475,7 +486,6 @@
110
         self.notebook.append_page(project_panel, Gtk.Label(label=_("Project")))
111
         self.notebook.append_page(render_panel, Gtk.Label(label=_("Render")))
112
         self.notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
113
-        #self.notebook.set_show_tabs(False) 
114
 
115
         # Right notebook, used for Widescreen and Two row layouts
116
         self.right_notebook = Gtk.Notebook()
117
@@ -859,18 +869,32 @@
118
             and (widget == self.clip_editor_b)):
119
             updater.display_clip_in_monitor()
120
 
121
+    def layouts_pressed(self, widget, event):
122
+        print "kkkkkkkkkkkkkkkkkkk"
123
+
124
     def connect_player(self, mltplayer):
125
         # Buttons
126
         # NOTE: ORDER OF CALLBACKS IS THE SAME AS ORDER OF BUTTONS FROM LEFT TO RIGHT
127
-        pressed_callback_funcs = [monitorevent.prev_pressed,
128
-                                  monitorevent.next_pressed,
129
-                                  monitorevent.play_pressed,
130
-                                  monitorevent.stop_pressed,
131
-                                  monitorevent.mark_in_pressed,
132
-                                  monitorevent.mark_out_pressed,
133
-                                  monitorevent.marks_clear_pressed,
134
-                                  monitorevent.to_mark_in_pressed,
135
-                                  monitorevent.to_mark_out_pressed]
136
+        # Jul-2016 - SvdB - For play/pause button
137
+        if editorpersistance.prefs.play_pause == False:
138
+            pressed_callback_funcs = [monitorevent.prev_pressed,
139
+                                      monitorevent.next_pressed,
140
+                                      monitorevent.play_pressed,
141
+                                      monitorevent.stop_pressed,
142
+                                      monitorevent.mark_in_pressed,
143
+                                      monitorevent.mark_out_pressed,
144
+                                      monitorevent.marks_clear_pressed,
145
+                                      monitorevent.to_mark_in_pressed,
146
+                                      monitorevent.to_mark_out_pressed]
147
+        else:
148
+            pressed_callback_funcs = [monitorevent.prev_pressed,
149
+                                      monitorevent.next_pressed,
150
+                                      monitorevent.play_pressed,
151
+                                      monitorevent.mark_in_pressed,
152
+                                      monitorevent.mark_out_pressed,
153
+                                      monitorevent.marks_clear_pressed,
154
+                                      monitorevent.to_mark_in_pressed,
155
+                                      monitorevent.to_mark_out_pressed]
156
         self.player_buttons.set_callbacks(pressed_callback_funcs)
157
 
158
         # Monitor position bar
159
@@ -956,30 +980,34 @@
160
             gdk_window = gui.tline_display.get_parent_window();
161
             gdk_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR))
162
 
163
+    def get_own_cursor(self, display, surface, hotx, hoty):
164
+        pixbuf = Gdk.pixbuf_get_from_surface(surface, 0, 0, surface.get_width(), surface.get_height())
165
+        return Gdk.Cursor.new_from_pixbuf(display, pixbuf, hotx, hoty)
166
+
167
     def set_tline_cursor(self, mode):
168
         display = Gdk.Display.get_default()
169
         gdk_window = self.window.get_window()#gui.tline_display.get_window()
170
 
171
         if mode == editorstate.INSERT_MOVE:
172
-            cursor = Gdk.Cursor.new_from_surface(display, INSERTMOVE_CURSOR, 0, 0)
173
+            cursor = self.get_own_cursor(display, INSERTMOVE_CURSOR, 0, 0)
174
         elif mode == editorstate.OVERWRITE_MOVE:
175
-            cursor = Gdk.Cursor.new_from_surface(display, OVERWRITE_CURSOR, 6, 15)
176
+            cursor = self.get_own_cursor(display, OVERWRITE_CURSOR, 6, 15)
177
         elif mode == editorstate.TWO_ROLL_TRIM:
178
-            cursor = Gdk.Cursor.new_from_surface(display, TWOROLL_CURSOR, 11, 9)
179
+            cursor = self.get_own_cursor(display, TWOROLL_CURSOR, 11, 9)
180
         elif mode == editorstate.TWO_ROLL_TRIM_NO_EDIT:
181
-            cursor = Gdk.Cursor.new_from_surface(display, TWOROLL_NO_EDIT_CURSOR, 11, 9)
182
+            cursor = self.get_own_cursor(display, TWOROLL_NO_EDIT_CURSOR, 11, 9)
183
         elif mode == editorstate.ONE_ROLL_TRIM:
184
-            cursor = Gdk.Cursor.new_from_surface(display, ONEROLL_CURSOR, 9, 9)
185
+            cursor = self.get_own_cursor(display, ONEROLL_CURSOR, 9, 9)
186
         elif mode == editorstate.ONE_ROLL_TRIM_NO_EDIT:
187
-            cursor = Gdk.Cursor.new_from_surface(display, ONEROLL_NO_EDIT_CURSOR, 9, 9)
188
+            cursor = self.get_own_cursor(display, ONEROLL_NO_EDIT_CURSOR, 9, 9)
189
         elif mode == editorstate.SLIDE_TRIM:
190
-            cursor = Gdk.Cursor.new_from_surface(display, SLIDE_CURSOR, 9, 9)
191
+            cursor = self.get_own_cursor(display, SLIDE_CURSOR, 9, 9)
192
         elif mode == editorstate.SLIDE_TRIM_NO_EDIT:
193
-            cursor = Gdk.Cursor.new_from_surface(display, SLIDE_NO_EDIT_CURSOR, 9, 9)
194
+            cursor = self.get_own_cursor(display, SLIDE_NO_EDIT_CURSOR, 9, 9)
195
         elif mode == editorstate.SELECT_PARENT_CLIP:
196
-            cursor =  Gdk.Cursor.new(Gdk.TCROSS)
197
+            cursor =  Gdk.Cursor.new(Gdk.CursorType.TCROSS)
198
         elif mode == editorstate.MULTI_MOVE:
199
-            cursor = Gdk.Cursor.new_from_surface(display, MULTIMOVE_CURSOR, 4, 8)
200
+            cursor = self.get_own_cursor(display, MULTIMOVE_CURSOR, 4, 8)
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/exporting.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/exporting.py Changed
201
 
1
@@ -32,6 +32,7 @@
2
 import re
3
 import shutil
4
 
5
+import appconsts
6
 import dialogs
7
 import dialogutils
8
 from editorstate import PLAYER
9
@@ -42,18 +43,9 @@
10
 import renderconsumer
11
 import utils
12
 
13
-EDL_TYPE_AVID_CMX3600 = 0
14
-
15
-AUDIO_FROM_VIDEO = 0
16
-AUDIO_FROM_AUDIO_TRACK = 1
17
-NO_AUDIO = 2
18
-
19
-REEL_NAME_3_NUMBER = 0
20
-REEL_NAME_8_NUMBER = 1
21
+REEL_NAME_HASH_8_NUMBER = 1
22
 REEL_NAME_FILE_NAME_START = 2
23
 
24
-CLIP_OUT_IS_LAST_FRAME = -999
25
-
26
 _xml_render_player = None
27
 
28
 _screenshot_img = None
29
@@ -68,7 +60,7 @@
30
     if response_id == Gtk.ResponseType.ACCEPT:
31
         filenames = dialog.get_filenames()
32
         save_path = filenames[0]
33
-        global _xml_render_monitor
34
+        #global _xml_render_monitor
35
         _xml_render_player = renderconsumer.XMLRenderPlayer(save_path,
36
                                                           _xml_render_done,
37
                                                           None)
38
@@ -88,14 +80,14 @@
39
 def EDL_export():
40
     dialogs.export_edl_dialog(_export_edl_dialog_callback, gui.editor_window.window, PROJECT().name)
41
 
42
-def _export_edl_dialog_callback(dialog, response_id, data):
43
-    if response_id == Gtk.ResponseType.YES:
44
-        file_name, out_folder, track_select_combo, cascade_check, op_combo, audio_track_select_combo = data
45
-        edl_path = out_folder.get_filename()+ "/" + file_name.get_text() + ".edl" 
46
-        global _xml_render_monitor
47
+def _export_edl_dialog_callback(dialog, response_id):
48
+    if response_id == Gtk.ResponseType.ACCEPT:
49
+        filenames = dialog.get_filenames()
50
+        edl_path = filenames[0]
51
+        
52
         _xml_render_player = renderconsumer.XMLRenderPlayer(get_edl_temp_xml_path(),
53
                                                             _edl_xml_render_done,
54
-                                                            (edl_path, track_select_combo, cascade_check, op_combo, audio_track_select_combo))
55
+                                                            edl_path)
56
         _xml_render_player.start()
57
 
58
         dialog.destroy()
59
@@ -103,32 +95,30 @@
60
         dialog.destroy()
61
 
62
 def _edl_xml_render_done(data):
63
-    edl_path, track_select_combo, cascade_check, op_combo, audio_track_select_combo = data
64
-    video_track = current_sequence().first_video_index + track_select_combo.get_active()
65
-    audio_track = 1 + audio_track_select_combo.get_active()
66
-    global _xml_render_player
67
-    _xml_render_player = None
68
-    mlt_parse = MLTXMLToEDLParse(get_edl_temp_xml_path(), edl_path)
69
-    edl_contents = mlt_parse.create_edl(video_track, 
70
-                                        cascade_check.get_active(),
71
-                                        op_combo.get_active(), 
72
-                                        audio_track)
73
+    edl_path  = data
74
+    mlt_parse = MLTXMLToEDLParse(get_edl_temp_xml_path(), current_sequence())
75
+    edl_contents = mlt_parse.create_edl()
76
     f = open(edl_path, 'w')
77
     f.write(edl_contents)
78
     f.close()
79
 
80
+
81
 def get_edl_temp_xml_path():
82
     return utils.get_hidden_user_dir_path() + "edl_temp_xml.xml"
83
 
84
 
85
 class MLTXMLToEDLParse:
86
-    def __init__(self, xmlfile, title):
87
+    def __init__(self, xmlfile, current_sequence):
88
         self.xmldoc = minidom.parse(xmlfile)
89
-        self.title = title
90
+        self.current_sequence = current_sequence
91
+
92
+        self.producers = {} # producer id -> producer_data
93
+        self.resource_to_reel_name = {}
94
+        self.reel_name_to_resource = {}
95
+        
96
         self.reel_name_type = REEL_NAME_FILE_NAME_START
97
-        self.from_clip_comment = False
98
+        self.from_clip_comment = True
99
         self.use_drop_frames = False
100
-        self.blender_fix = False
101
 
102
     def get_project_profile(self):
103
         profile_dict = {}
104
@@ -150,105 +140,94 @@
105
         playlists = self.xmldoc.getElementsByTagName("playlist")
106
         eid = 0
107
         for p in playlists:
108
-            event_list = []
109
-            pl_dict = {}
110
-            pl_dict["pid"] = p.attributes["id"].value
111
+            
112
+            track_id_attr_value = p.attributes["id"].value
113
+
114
+            # Don't empty, black or hidden tracks
115
+            if track_id_attr_value == "playlist0":
116
+                continue
117
+            
118
+            if len(p.getElementsByTagName("entry")) < 1:
119
+                continue
120
+                
121
+            # plist contains id and events list data
122
+            plist = {}
123
+            plist["pl_id"] = track_id_attr_value
124
  
125
+            # Set track type info
126
+            track_index = int(track_id_attr_value.lstrip("playlist"))
127
+            track_object =  self.current_sequence.tracks[track_index]
128
+            plist["src_channel"] =  "AA/V" 
129
+            if track_object.type == appconsts.AUDIO:
130
+                plist["src_channel"] = "AA"
131
+                        
132
+            # Create events list
133
+            event_list = []
134
             event_nodes = p.childNodes
135
             events = []
136
             for i in range(0, event_nodes.length):
137
                 # Get edit event
138
-                event = event_nodes.item(i)
139
+                event_node = event_nodes.item(i)
140
                 
141
-                # Create event dict and give it id
142
-                ev_dict = {}
143
-                ev_dict["eid"] = eid
144
+                # Create event  and give it id
145
+                event = {}
146
+                event["eid"] = eid
147
                 eid = eid + 1
148
                 
149
                 # Set event data
150
-                if event.localName == "entry":# or  event.localName == "blank":
151
-                    ev_dict["type"] = event.localName
152
-                    ev_dict["producer"] = event.attributes["producer"].value
153
-                    ev_dict["inTime"] = event.attributes["in"].value
154
-                    ev_dict["outTime"] = event.attributes["out"].value
155
-                    event_list.append(ev_dict)
156
-                elif  event.localName == "blank":
157
-                    ev_dict["type"] = event.localName
158
-                    ev_dict["length"] = event.attributes["length"].value
159
-                    event_list.append(ev_dict)
160
-
161
-            pl_dict["events"] = event_list
162
-            playlist_list.append(pl_dict)
163
+                if event_node.localName == "entry":# or  event.localName == "blank":
164
+                    event["type"] = event_node.localName
165
+                    event["producer"] = event_node.attributes["producer"].value
166
+                    event["inTime"] = event_node.attributes["in"].value
167
+                    event["outTime"] = event_node.attributes["out"].value
168
+                    event_list.append(event)
169
+                elif event_node.localName == "blank":
170
+                    event["type"] = event_node.localName
171
+                    event["length"] = event_node.attributes["length"].value
172
+                    event_list.append(event)
173
+
174
+            plist["events_list"] = event_list
175
+            
176
+            # Add to playlists list
177
+            playlist_list.append(plist)
178
+            
179
         return tuple(playlist_list)
180
 
181
-    def get_events_dict(self, playlists, source_links):
182
-        events_dict = {}
183
-        for play_list in playlists:
184
-            for event in play_list["events"]:
185
-                # Replace pattern producer events with blanks
186
-                try:
187
-                    producer = event["producer"]
188
-                    resource = source_links[producer]
189
-                    if resource == "<producer>" or resource[0:1] == "#": # This is what MLT puts as resource for pattern producers or color clips
190
-                        event["type"] = "blank"
191
-                        event["length"] =  int(event["outTime"]) - int(event["inTime"]) + 1
192
-                except:
193
-                    pass
194
-
195
-                # Add events to event dict
196
-                eid = event["eid"]
197
-                events_dict[eid] = event
198
-        return events_dict
199
-
200
-    def get_producers(self):
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/glassbuttons.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/glassbuttons.py Changed
158
 
1
@@ -26,7 +26,6 @@
2
 import cairoarea
3
 import editorpersistance
4
 import gui
5
-#import guiutils
6
 import respaths
7
 
8
 BUTTONS_GRAD_STOPS = [   (1, 1, 1, 1, 0.2),
9
@@ -55,6 +54,8 @@
10
 MB_BUTTON_Y = 4
11
 MB_BUTTON_IMAGE_Y = 6
12
 
13
+GMIC_BUTTONS_WIDTH = 250
14
+
15
 M_PI = math.pi
16
 
17
 NO_HIT = -1
18
@@ -93,7 +94,7 @@
19
         self.image_x = []
20
         self.image_y = []
21
         self.sensitive = []
22
-        
23
+
24
         if editorpersistance.prefs.buttons_style == editorpersistance.GLASS_STYLE:
25
             self.glass_style = True
26
         else:
27
@@ -262,6 +263,9 @@
28
         AbstractGlassButtons.__init__(self, MB_BUTTON_WIDTH, MB_BUTTON_HEIGHT, MB_BUTTON_Y, MB_BUTTONS_WIDTH, MB_BUTTONS_HEIGHT)
29
 
30
         IMG_PATH = respaths.IMAGE_PATH
31
+        # Jul-2016 - SvdB - Modified to replace play/stop combo by single play/pause button, if option is set
32
+        play_pause_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "play_pause_s.png")
33
+        #
34
         play_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "play_2_s.png")
35
         stop_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "stop_s.png")
36
         next_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "next_frame_s.png")
37
@@ -272,10 +276,17 @@
38
         to_mark_in_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "to_mark_in_s.png")        
39
         to_mark_out_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "to_mark_out_s.png") 
40
 
41
-        self.icons = [prev_icon, next_icon, play_icon, stop_icon, 
42
-                      mark_in_icon, mark_out_icon, 
43
-                      marks_clear_icon, to_mark_in_icon, to_mark_out_icon]
44
-        self.image_x = [8, 10, 13, 13, 6, 14, 5, 10, 9]
45
+        # Jul-2016 - SvdB - For play/pause button
46
+        if (editorpersistance.prefs.play_pause == True):
47
+            self.icons = [prev_icon, next_icon, play_pause_icon,
48
+                          mark_in_icon, mark_out_icon, 
49
+                          marks_clear_icon, to_mark_in_icon, to_mark_out_icon]
50
+            self.image_x = [8, 10, 8, 6, 14, 5, 10, 9]
51
+        else:
52
+            self.icons = [prev_icon, next_icon, play_icon, stop_icon, 
53
+                          mark_in_icon, mark_out_icon, 
54
+                          marks_clear_icon, to_mark_in_icon, to_mark_out_icon]
55
+            self.image_x = [8, 10, 13, 13, 6, 14, 5, 10, 9]
56
 
57
         for i in range(0, len(self.icons)):
58
             self.image_y.append(MB_BUTTON_IMAGE_Y)
59
@@ -287,7 +298,11 @@
60
         focus_groups[DEFAULT_FOCUS_GROUP].append(self.widget)
61
 
62
     def set_trim_sensitive_pattern(self):
63
-        self.sensitive = [True, True, True, True, False, False, False, False, False]
64
+        # Jul-2016 - SvdB - For play/pause button
65
+        if (editorpersistance.prefs.play_pause == True):
66
+            self.sensitive = [True, True, True, False, False, False, False, False]
67
+        else:
68
+            self.sensitive = [True, True, True, True, False, False, False, False, False]
69
         self.widget.queue_draw()
70
 
71
     def set_normal_sensitive_pattern(self):
72
@@ -331,10 +346,85 @@
73
 
74
         mid_x = w / 2
75
         buttons_width = self.button_width * len(self.icons)
76
+        # Jul-2016 - SvdB - No changes made here, but because of the calculation of button_x the row of buttons is slightly moved right if play/pause
77
+        # is enabled. This could be solved by setting self.button_x = 1, if wished.
78
         self.button_x = mid_x - (buttons_width / 2)
79
         self._draw_buttons(cr, w, h)
80
 
81
 
82
+class GmicButtons(AbstractGlassButtons):
83
+
84
+    def __init__(self):
85
+
86
+        AbstractGlassButtons.__init__(self, MB_BUTTON_WIDTH, MB_BUTTON_HEIGHT, MB_BUTTON_Y, GMIC_BUTTONS_WIDTH, MB_BUTTONS_HEIGHT)
87
+
88
+        IMG_PATH = respaths.IMAGE_PATH
89
+        next_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "next_frame_s.png")
90
+        prev_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "prev_frame_s.png")
91
+        mark_in_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "mark_in_s.png")
92
+        mark_out_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "mark_out_s.png")
93
+        marks_clear_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "marks_clear_s.png") 
94
+        to_mark_in_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "to_mark_in_s.png")        
95
+        to_mark_out_icon = cairo.ImageSurface.create_from_png(IMG_PATH + "to_mark_out_s.png") 
96
+
97
+        self.icons = [prev_icon, next_icon, mark_in_icon, mark_out_icon, 
98
+                      marks_clear_icon, to_mark_in_icon, to_mark_out_icon]
99
+        self.image_x = [8, 10, 6, 14, 5, 10, 9]
100
+
101
+        for i in range(0, len(self.icons)):
102
+            self.image_y.append(MB_BUTTON_IMAGE_Y)
103
+
104
+        self.pressed_callback_funcs = None # set using set_callbacks()
105
+
106
+        self.set_sensitive(True)
107
+        
108
+        focus_groups[DEFAULT_FOCUS_GROUP].append(self.widget)
109
+
110
+
111
+    def set_normal_sensitive_pattern(self):
112
+        self.set_sensitive(True)
113
+        self.widget.queue_draw()
114
+
115
+    # ------------------------------------------------------------- mouse events
116
+    def _press_event(self, event):
117
+        """
118
+        Mouse button callback
119
+        """
120
+        self.pressed_button = self._get_hit_code(event.x, event.y)
121
+        if self.pressed_button >= 0 and self.pressed_button < len(self.icons):
122
+            callback_func = self.pressed_callback_funcs[self.pressed_button] # index is set to match at editorwindow.py where callback func list is created
123
+            callback_func()
124
+        self.widget.queue_draw()
125
+
126
+    def _motion_notify_event(self, x, y, state):
127
+        """
128
+        Mouse move callback
129
+        """
130
+        button_under = self._get_hit_code(x, y)
131
+        if self.pressed_button != button_under: # pressed button is released
132
+            self.pressed_button = NO_HIT
133
+        self.widget.queue_draw()
134
+
135
+    def _release_event(self, event):
136
+        """
137
+        Mouse release callback
138
+        """
139
+        self.pressed_button = -1
140
+        self.widget.queue_draw()
141
+
142
+    def set_callbacks(self, pressed_callback_funcs):
143
+        self.pressed_callback_funcs = pressed_callback_funcs 
144
+
145
+    # ---------------------------------------------------------------- painting
146
+    def _draw(self, event, cr, allocation):
147
+        x, y, w, h = allocation
148
+        self.allocation = allocation
149
+
150
+        mid_x = w / 2
151
+        buttons_width = self.button_width * len(self.icons)
152
+        self.button_x = mid_x - (buttons_width / 2)
153
+        self._draw_buttons(cr, w, h)
154
+
155
 class GlassButtonsGroup(AbstractGlassButtons):
156
 
157
     def __init__(self, button_width, button_height, button_y, image_x_default, image_y_default, focus_group=DEFAULT_FOCUS_GROUP):
158
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/gui.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/gui.py Changed
73
 
1
@@ -24,8 +24,10 @@
2
 
3
 from gi.repository import Gtk, Gdk
4
 
5
-import editorpersistance
6
+import pickle
7
 
8
+import editorpersistance
9
+import utils
10
 
11
 # Editor window
12
 editor_window = None
13
@@ -83,6 +85,8 @@
14
 
15
 _THEME_COLORS = (_UBUNTU_COLORS, _GNOME_COLORS, _MINT_COLORS, _ARC_COLORS)
16
 
17
+_CURRENT_THEME_COLORS_FILE = "currentcolors.data"
18
+
19
 _selected_bg_color = None
20
 _bg_color = None
21
 _button_colors = None
22
@@ -139,15 +143,15 @@
23
 # returns Gdk.RGBA color
24
 def get_buttons_color():
25
     return _button_colors
26
-    
27
+
28
 def set_theme_colors():
29
-    # Find out if theme color discovery works and set selected bg color apppropiately when 
30
+    # Find out if theme color discovery works and set selected bg color apppropiately when
31
     # this is first called.
32
     global _selected_bg_color, _bg_color, _button_colors
33
 
34
     fallback_theme_colors = editorpersistance.prefs.theme_fallback_colors
35
     theme_colors = _THEME_COLORS[fallback_theme_colors]
36
-    
37
+
38
     # Try to detect selected color and set from fallback if fails
39
     style = editor_window.bin_list_view.get_style_context()
40
     sel_bg_color = style.get_background_color(Gtk.StateFlags.SELECTED)
41
@@ -186,10 +190,30 @@
42
     editor_window.tline_pane.override_background_color(Gtk.StateFlags.NORMAL, get_bg_color())
43
     editor_window.media_panel.override_background_color(Gtk.StateFlags.NORMAL, get_bg_color())
44
     editor_window.mm_paned.override_background_color(Gtk.StateFlags.NORMAL, get_bg_color())
45
-    
46
+
47
 def unpack_gdk_color(gdk_color):
48
     return (gdk_color.red, gdk_color.green, gdk_color.blue, gdk_color.alpha)
49
 
50
+def save_current_colors():
51
+    # Used to communicate theme colors to tools like gmic.py running on separate process
52
+    colors = (unpack_gdk_color(_selected_bg_color), unpack_gdk_color(_bg_color), unpack_gdk_color(_button_colors))
53
+    save_file_path = _colors_data_path()
54
+    write_file = file(save_file_path, "wb")
55
+    pickle.dump(colors, write_file)
56
+
57
+def load_current_colors():
58
+    load_path = _colors_data_path()
59
+    f = open(load_path)
60
+    colors = pickle.load(f)
61
+    sel, bg, button = colors
62
+    global _selected_bg_color, _bg_color, _button_colors
63
+    _selected_bg_color = Gdk.RGBA(*sel)
64
+    _bg_color = Gdk.RGBA(*bg)
65
+    _button_colors = Gdk.RGBA(*button)
66
+
67
+def _colors_data_path():
68
+    return utils.get_hidden_user_dir_path() + _CURRENT_THEME_COLORS_FILE
69
+
70
 def _print_widget(widget): # debug
71
     path_str = widget.get_path().to_string()
72
     path_str = path_str.replace("GtkWindow:dir-ltr.background","")
73
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/guicomponents.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/guicomponents.py Changed
201
 
1
@@ -24,6 +24,7 @@
2
 
3
 import cairo
4
 import math
5
+import time
6
 
7
 from gi.repository import GObject
8
 from gi.repository import GdkPixbuf
9
@@ -47,6 +48,7 @@
10
 import mltprofiles
11
 import mlttransitions
12
 import respaths
13
+import snapping
14
 import translations
15
 import utils
16
 
17
@@ -68,7 +70,7 @@
18
                         (0.51, 1, 1, 1, 0),
19
                         (0.50, 1, 1, 1, 0.25),
20
                         (0, 1, 1, 1, 0.4)]
21
-                        
22
+
23
 BIG_TC_FRAME_GRAD_STOPS = [ (1, 0.7, 0.7, 0.7, 1),
24
                             (0.95, 0.7, 0.7, 0.7, 1),
25
                             (0.75, 0.1, 0.1, 0.1, 1),
26
@@ -81,6 +83,7 @@
27
 imgseq_icon = None
28
 audio_icon = None
29
 pattern_icon = None
30
+profile_warning_icon = None
31
 
32
 # GTK3 requires these to be created outside of callback
33
 markers_menu = Gtk.Menu.new()
34
@@ -101,7 +104,7 @@
35
 log_event_popup_menu = Gtk.Menu()
36
 levels_menu = Gtk.Menu()
37
 
38
-# ------------------------------------------------- item lists 
39
+# ------------------------------------------------- item lists
40
 class ImageTextTextListView(Gtk.VBox):
41
     """
42
     GUI component displaying list with columns: img, text, text
43
@@ -110,10 +113,10 @@
44
 
45
     def __init__(self):
46
         GObject.GObject.__init__(self)
47
-       
48
+
49
        # Datamodel: icon, text, text
50
         self.storemodel = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str)
51
- 
52
+
53
         # Scroll container
54
         self.scroll = Gtk.ScrolledWindow()
55
         self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
56
@@ -130,7 +133,7 @@
57
         self.icon_col = Gtk.TreeViewColumn("Icon")
58
         self.text_col_1 = Gtk.TreeViewColumn("text1")
59
         self.text_col_2 = Gtk.TreeViewColumn("text2")
60
-        
61
+
62
         # Cell renderers
63
         self.icon_rend = Gtk.CellRendererPixbuf()
64
         self.icon_rend.props.xpad = 6
65
@@ -146,7 +149,7 @@
66
         self.icon_col.set_spacing(5)
67
         self.icon_col.pack_start(self.icon_rend, False)
68
         self.icon_col.add_attribute(self.icon_rend, 'pixbuf', 0)
69
-        
70
+
71
         self.text_col_1.set_expand(True)
72
         self.text_col_1.set_spacing(5)
73
         self.text_col_1.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY)
74
@@ -157,7 +160,7 @@
75
         self.text_col_2.set_expand(False)
76
         self.text_col_2.pack_start(self.text_rend_2, True)
77
         self.text_col_2.add_attribute(self.text_rend_2, "text", 2)
78
-        
79
+
80
         # Add column views to view
81
         self.treeview.append_column(self.icon_col)
82
         self.treeview.append_column(self.text_col_1)
83
@@ -173,7 +176,7 @@
84
         return rows
85
 
86
 
87
-# ------------------------------------------------- item lists 
88
+# ------------------------------------------------- item lists
89
 class ImageTextImageListView(Gtk.VBox):
90
     """
91
     GUI component displaying list with columns: img, text, img
92
@@ -182,10 +185,10 @@
93
 
94
     def __init__(self):
95
         GObject.GObject.__init__(self)
96
-        
97
+
98
        # Datamodel: icon, text, icon
99
         self.storemodel = Gtk.ListStore(GdkPixbuf.Pixbuf, str, GdkPixbuf.Pixbuf)
100
- 
101
+
102
         # Scroll container
103
         self.scroll = Gtk.ScrolledWindow()
104
         self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
105
@@ -202,7 +205,7 @@
106
         self.icon_col_1 = Gtk.TreeViewColumn("icon1")
107
         self.text_col_1 = Gtk.TreeViewColumn("text1")
108
         self.icon_col_2 = Gtk.TreeViewColumn("icon2")
109
-        
110
+
111
         # Cell renderers
112
         self.icon_rend_1 = Gtk.CellRendererPixbuf()
113
         self.icon_rend_1.props.xpad = 6
114
@@ -218,7 +221,7 @@
115
         self.icon_col_1.set_spacing(5)
116
         self.icon_col_1.pack_start(self.icon_rend_1, False)
117
         self.icon_col_1.add_attribute(self.icon_rend_1, 'pixbuf', 0)
118
-        
119
+
120
         self.text_col_1.set_expand(True)
121
         self.text_col_1.set_spacing(5)
122
         self.text_col_1.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY)
123
@@ -230,7 +233,7 @@
124
         self.icon_col_2.set_spacing(5)
125
         self.icon_col_2.pack_start(self.icon_rend_2, False)
126
         self.icon_col_2.add_attribute(self.icon_rend_2, 'pixbuf', 2)
127
-        
128
+
129
         # Add column views to view
130
         self.treeview.append_column(self.icon_col_1)
131
         self.treeview.append_column(self.text_col_1)
132
@@ -253,14 +256,14 @@
133
 
134
     def __init__(self, seq_name_edited_cb):
135
         ImageTextTextListView.__init__(self)
136
-        
137
+
138
         # Icon path
139
-        self.icon_path = respaths.IMAGE_PATH + "sequence.png" 
140
-        
141
+        self.icon_path = respaths.IMAGE_PATH + "sequence.png"
142
+
143
         # Set sequence name editable and connect 'edited' signal
144
         self.text_rend_1.set_property("editable", True)
145
-        self.text_rend_1.connect("edited", 
146
-                                 seq_name_edited_cb, 
147
+        self.text_rend_1.connect("edited",
148
+                                 seq_name_edited_cb,
149
                                  (self.storemodel, 1))
150
 
151
     def fill_data_model(self):
152
@@ -275,12 +278,12 @@
153
             if seq == current_sequence():
154
                 active = _("active") + " "
155
             row_data = [icon,
156
-                        seq.name, 
157
+                        seq.name,
158
                         active]
159
             self.storemodel.append(row_data)
160
             self.scroll.queue_draw()
161
 
162
-       
163
+
164
 class MediaListView(ImageTextTextListView):
165
     """
166
     GUI component displaying list of media files.
167
@@ -290,17 +293,17 @@
168
         ImageTextTextListView.__init__(self)
169
 
170
         # Connect double-click listener and allow multiple selection
171
-        self.treeview.connect("row-activated", 
172
+        self.treeview.connect("row-activated",
173
                               row_activated_cb)
174
 
175
         tree_sel = self.treeview.get_selection()
176
         tree_sel.set_mode(Gtk.SelectionMode.MULTIPLE)
177
         self.text_rend_1.set_property("editable", True)
178
         self.text_rend_1.set_property("font-desc", Pango.FontDescription("sans bold 9"))
179
-        self.text_rend_1.connect("edited", 
180
-                                 file_name_edited_cb, 
181
+        self.text_rend_1.connect("edited",
182
+                                 file_name_edited_cb,
183
                                  (self.storemodel, 1))
184
-                                 
185
+
186
         self.text_rend_2.set_property("font-desc", Pango.FontDescription("sans 8"))
187
         self.text_rend_2.set_property("yalign", 0.5)
188
 
189
@@ -313,11 +316,11 @@
190
         for file_id in current_bin().file_ids:
191
             media_file = PROJECT().media_files[file_id]
192
             row_data = [media_file.icon,
193
-                        media_file.name, 
194
+                        media_file.name,
195
                         utils.clip_length_string(media_file.length)]
196
             self.storemodel.append(row_data)
197
             self.scroll.queue_draw()
198
-            
199
+
200
 
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/guiutils.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/guiutils.py Changed
26
 
1
@@ -118,7 +118,7 @@
2
     hbox.pack_start(widget2, False, False, 0)
3
     hbox.pack_start(Gtk.Label(), True, True, 0)
4
     return hbox
5
-    
6
+
7
 def get_two_row_box(widget1, widget2):
8
     # widget 1 is left justified
9
     top = get_left_justified_box([widget1])
10
@@ -234,7 +234,6 @@
11
 
12
     alignment = set_margins(widget, right_padding, 0, left_padding, 0)
13
 
14
-    
15
     frame = Gtk.VBox()
16
     if name != None:
17
         frame.pack_start(label_box, False, False, 0)
18
@@ -250,7 +249,6 @@
19
     align.pack_start(widget, False, False, 0)
20
     align.pack_start(Gtk.Label(), True, True, 0)
21
 
22
-    
23
     return align
24
 
25
 def pad_label(w, h):
26
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/keyevents.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/keyevents.py Changed
46
 
1
@@ -42,6 +42,7 @@
2
 import monitorevent
3
 import mltrefhold
4
 import tlineaction
5
+import trimmodes
6
 import updater
7
 import projectaction
8
 
9
@@ -236,6 +237,23 @@
10
         medialog.log_range_clicked()
11
         return True
12
 
13
+
14
+    # Key bindings for keyboard trimming
15
+    if editorstate.current_is_active_trim_mode() == True:
16
+        # LEFT ARROW, prev frame
17
+        if event.keyval == Gdk.KEY_Left:
18
+            trimmodes.left_arrow_pressed((event.get_state() & Gdk.ModifierType.CONTROL_MASK))
19
+            return True
20
+
21
+        # RIGHT ARROW, next frame
22
+        if event.keyval == Gdk.KEY_Right:
23
+            trimmodes.right_arrow_pressed((event.get_state() & Gdk.ModifierType.CONTROL_MASK))
24
+            return True
25
+
26
+        if event.keyval == Gdk.KEY_Return:
27
+            trimmodes.enter_pressed()
28
+            return True
29
+
30
     # Key bindings for MOVE MODES and _NO_EDIT modes
31
     if editorstate.current_is_move_mode() or editorstate.current_is_active_trim_mode() == False:
32
          # UP ARROW, next cut
33
@@ -311,7 +329,11 @@
34
                 monitorevent.l_pressed()
35
             return True
36
 
37
-
38
+        # R
39
+        if event.keyval == Gdk.KEY_r:
40
+            tlineaction.resync_button_pressed()
41
+            return True
42
+            
43
         # DELETE
44
         if event.keyval == Gdk.KEY_Delete:
45
             # Clip selection and compositor selection are mutually exclusive, 
46
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/keyframeeditor.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/keyframeeditor.py Changed
21
 
1
@@ -1721,7 +1721,8 @@
2
     def prev_pressed(self):
3
         self.clip_editor.set_prev_active()
4
         self.update_editor_view()
5
-    
6
+        self.buttons_row.set_kf_info(self.clip_editor.get_kf_info())
7
+
8
     def prev_frame_pressed(self):
9
         self.clip_editor.move_clip_frame(-1)
10
         self.update_editor_view()
11
@@ -1867,7 +1868,8 @@
12
         self.geom_kf_edit.set_keyframe_to_edit_shape(self.clip_editor.active_kf_index)
13
         self.update_editor_view_with_frame(self.clip_editor.current_clip_frame)
14
         self.update_property_value()
15
-    
16
+        self.buttons_row.set_kf_info(self.clip_editor.get_kf_info())
17
+
18
     def arrow_edit(self, keyval):
19
         self.geom_kf_edit.handle_arrow_edit(keyval)
20
         self.geom_kf_edit.set_keyframe_to_edit_shape(self.clip_editor.active_kf_index)
21
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/launch/flowbladegmic Added
32
 
1
@@ -0,0 +1,30 @@
2
+#!/usr/bin/env python
3
+
4
+import sys
5
+import os
6
+
7
+
8
+modules_path = os.path.dirname(os.path.abspath(sys.argv[0])).rstrip("/launch")
9
+
10
+sys.path.insert(0, modules_path)
11
+sys.path.insert(0, modules_path + "/vieweditor")
12
+sys.path.insert(0, modules_path + "/tools")
13
+
14
+# Get app.py module and set info which type of installation is running
15
+try:
16
+    import gmic
17
+    import editorstate # Used to decide which translations from file system are used
18
+    root_dir = modules_path.split("/")[1]
19
+    if root_dir != "home":
20
+        editorstate.app_running_from = editorstate.RUNNING_FROM_INSTALLATION
21
+    else:
22
+        editorstate.app_running_from = editorstate.RUNNING_FROM_DEV_VERSION
23
+except Exception, err:
24
+    print "Failed to import gmic"
25
+    print "ERROR:", err
26
+    print "Installation was assumed to be at:", modules_path
27
+    sys.exit(1)
28
+    
29
+
30
+
31
+gmic.main(modules_path)
32
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/launch/flowblademedialinker -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/launch/flowblademedialinker Changed
24
 
1
@@ -10,6 +10,20 @@
2
 sys.path.insert(0, modules_path + "/vieweditor")
3
 sys.path.insert(0, modules_path + "/tools")
4
 
5
-import medialinker
6
 
7
-medialinker.main(modules_path)
8
+try:
9
+    import medialinker
10
+    import editorstate # Used to decide which translations from file system are used
11
+    root_dir = modules_path.split("/")[1]
12
+    if root_dir != "home":
13
+        editorstate.app_running_from = editorstate.RUNNING_FROM_INSTALLATION
14
+    else:
15
+        editorstate.app_running_from = editorstate.RUNNING_FROM_DEV_VERSION
16
+except Exception, err:
17
+    print "Failed to import medialinker"
18
+    print "ERROR:", err
19
+    print "Installation was assumed to be at:", modules_path
20
+    sys.exit(1)
21
+
22
+
23
+medialinker.main(modules_path, sys.argv[1]) # sys.argv[1] is possibly a file path to project to be opened at startup
24
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/launch/flowbladephantom Added
13
 
1
@@ -0,0 +1,11 @@
2
+#!/usr/bin/env bash
3
+
4
+# Get lanch data
5
+JAR_PATH=$1
6
+
7
+# Launch Phantom
8
+echo "rrr"
9
+echo "jarpath:"$JAR_PATH
10
+echo "$@"
11
+
12
+java -jar $JAR_PATH "$@"
13
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/Flowblade/flowblade.pot -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/Flowblade/flowblade.pot Changed
201
 
1
@@ -8,7 +8,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2015-11-23 20:30+0200\n"
6
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
7
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
 "Language-Team: LANGUAGE <LL@li.org>\n"
10
@@ -17,514 +17,544 @@
11
 "Content-Type: text/plain; charset=CHARSET\n"
12
 "Content-Transfer-Encoding: 8bit\n"
13
 
14
-#: app.py:685
15
+#: app.py:733
16
 msgid "Too small screen for this application."
17
 msgstr ""
18
 
19
-#: app.py:688
20
+#: app.py:736
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr ""
23
 
24
-#: app.py:689
25
+#: app.py:737
26
 msgid "Your screen dimensions are "
27
 msgstr ""
28
 
29
-#: app.py:724
30
+#: app.py:761
31
 msgid "Project has not been saved since it was opened."
32
 msgstr ""
33
 
34
-#: app.py:729
35
+#: app.py:766
36
 msgid "Project was saved less than a minute ago."
37
 msgstr ""
38
 
39
-#: app.py:732
40
+#: app.py:769
41
 msgid "Project was saved one minute ago."
42
 msgstr ""
43
 
44
-#: app.py:734
45
+#: app.py:771
46
 msgid "Project was saved "
47
 msgstr ""
48
 
49
-#: app.py:734
50
+#: app.py:771
51
 msgid " minutes ago."
52
 msgstr ""
53
 
54
-#: app.py:744 projectaction.py:278
55
+#: app.py:781 projectaction.py:327
56
 msgid "Project has not been saved previously"
57
 msgstr ""
58
 
59
-#: app.py:745 projectaction.py:279
60
+#: app.py:782 projectaction.py:328
61
 msgid "Save project with File -> Save As before closing."
62
 msgstr ""
63
 
64
-#: projectaction.py:106
65
+#: projectaction.py:111
66
 msgid "Media asset was missing!"
67
 msgstr ""
68
 
69
-#: projectaction.py:107
70
+#: projectaction.py:112
71
 msgid "Path of missing asset:"
72
 msgstr ""
73
 
74
-#: projectaction.py:108
75
+#: projectaction.py:113
76
 msgid ""
77
 "Relative search for replacement file in sub folders of project file failed."
78
 msgstr ""
79
 
80
-#: projectaction.py:109
81
+#: projectaction.py:114
82
 msgid "To load the project you will need to either:"
83
 msgstr ""
84
 
85
-#: projectaction.py:110
86
-msgid "Use 'Media Linker' tool to relink media assets to new files, or"
87
+#: projectaction.py:115
88
+msgid ""
89
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
90
 msgstr ""
91
 
92
-#: projectaction.py:111
93
+#: projectaction.py:116
94
 msgid "Place a file with the same exact name and path on the hard drive"
95
 msgstr ""
96
 
97
-#: projectaction.py:118
98
+#: projectaction.py:117
99
+msgid "Open project in Media Relinker tool"
100
+msgstr ""
101
+
102
+#: projectaction.py:136
103
 msgid "Profile with Description: '"
104
 msgstr ""
105
 
106
-#: projectaction.py:118
107
+#: projectaction.py:136
108
 msgid "' was not found on load!"
109
 msgstr ""
110
 
111
-#: projectaction.py:119
112
+#: projectaction.py:137
113
 msgid ""
114
 "It is possible to load the project by creating a User Profile with exactly "
115
 "the same Description\n"
116
 "as the missing profile. "
117
 msgstr ""
118
 
119
-#: projectaction.py:120
120
+#: projectaction.py:138
121
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
122
 msgstr ""
123
 
124
-#: projectaction.py:127
125
+#: projectaction.py:145
126
 msgid "Opening"
127
 msgstr ""
128
 
129
-#: projectaction.py:210
130
+#: projectaction.py:238
131
 msgid "Media files already present in project were opened!"
132
 msgstr ""
133
 
134
-#: projectaction.py:216
135
+#: projectaction.py:244
136
 msgid ""
137
 "Files already present:\n"
138
 "\n"
139
 msgstr ""
140
 
141
-#: projectaction.py:374
142
+#: projectaction.py:442
143
 msgid "Selected folder contains files"
144
 msgstr ""
145
 
146
-#: projectaction.py:375
147
+#: projectaction.py:443
148
 msgid ""
149
 "When saving a back-up snapshot of the project, the selected folder\n"
150
 "has to be empty."
151
 msgstr ""
152
 
153
-#: projectaction.py:401
154
+#: projectaction.py:501
155
 msgid "Copying project media assets"
156
 msgstr ""
157
 
158
-#: projectaction.py:402
159
+#: projectaction.py:502
160
 msgid "Saving project file"
161
 msgstr ""
162
 
163
-#: projectaction.py:525
164
+#: projectaction.py:625
165
 msgid "Project not found on disk"
166
 msgstr ""
167
 
168
-#: projectaction.py:526
169
+#: projectaction.py:626
170
 msgid "Project can't be loaded."
171
 msgstr ""
172
 
173
-#: projectaction.py:583
174
+#: projectaction.py:684
175
 msgid "Render launch failed!"
176
 msgstr ""
177
 
178
-#: projectaction.py:584 projectaction.py:598 tools/batchrendering.py:295
179
+#: projectaction.py:685 projectaction.py:699 tools/batchrendering.py:296
180
 msgid "Error message: "
181
 msgstr ""
182
 
183
-#: projectaction.py:597
184
+#: projectaction.py:698
185
 msgid "Adding item to render queue failed!"
186
 msgstr ""
187
 
188
-#: projectaction.py:616
189
+#: projectaction.py:717
190
 msgid "Open.."
191
 msgstr ""
192
 
193
-#: projectaction.py:643
194
+#: projectaction.py:747
195
 msgid "No file was selected"
196
 msgstr ""
197
 
198
-#: projectaction.py:643
199
+#: projectaction.py:747
200
 msgid "Select a numbered file to add an Image Sequence to Project."
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/add_language -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/add_language Changed
24
 
1
@@ -11,7 +11,7 @@
2
 ROOT_DIR=$(pwd)
3
 
4
 # Check if directory for translation already exists
5
-TRANS_FILE=$ROOT_DIR"/locale/"$LANG"/LC_MESSAGES/Flowblade.po"
6
+TRANS_FILE=$ROOT_DIR"/locale/"$LANG"/LC_MESSAGES/flowblade.po"
7
 if [ -f $TRANS_FILE ]; then
8
   echo "Translation files for $LANG_NAME already exist."
9
   echo "No new translation files were created."
10
@@ -28,11 +28,11 @@
11
 ./locale/create_pot
12
 
13
 # Create language .po file
14
-SOURCE_POT=$ROOT_DIR"/locale/Flowblade/Flowblade.pot"
15
+SOURCE_POT=$ROOT_DIR"/locale/Flowblade/flowblade.pot"
16
 msginit --output-file=$TRANS_FILE --input=$SOURCE_POT --locale=$LANG
17
 
18
 # Give info
19
-echo "New translation file for $LANG_NAME was created."
20
+echo "New translation file for $LANG was created."
21
 echo "Edit it and run 'compile_language $LANG' to compile binary file and test it."
22
 
23
 
24
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/create_pot -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/create_pot Changed
7
 
1
@@ -7,4 +7,4 @@
2
 ROOT_DIR=$(pwd)
3
 
4
 # Creates .pot file that can be turned to .po file for each language
5
-xgettext -o locale/Flowblade/flowblade.pot app.py projectaction.py editorwindow.py clipeffectseditor.py compositeeditor.py dialogs.py editevent.py editorpersistance.py guicomponents.py movemodes.py panels.py persistance.py projectdata.py render.py syncsplitevent.py translations.py mlttransitions.py propertyeditorbuilder.py keyframeeditor.py middlebar.py medialog.py projectinfogui.py tools/titler.py rendergui.py profilesmanager.py preferenceswindow.py tools/batchrendering.py proxyediting.py tlineaction.py extraeditors.py trackaction.py medialinker.py patternproducer.py
6
+xgettext -o locale/Flowblade/flowblade.pot app.py projectaction.py editorwindow.py clipeffectseditor.py compositeeditor.py dialogs.py editevent.py editorpersistance.py guicomponents.py movemodes.py panels.py persistance.py projectdata.py render.py syncsplitevent.py translations.py mlttransitions.py propertyeditorbuilder.py keyframeeditor.py middlebar.py medialog.py projectinfogui.py tools/titler.py rendergui.py profilesmanager.py preferenceswindow.py tools/batchrendering.py proxyediting.py tlineaction.py extraeditors.py trackaction.py medialinker.py patternproducer.py tools/gmic.py tools/gmic.py tools/toolsencoding.py
7
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.mo -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.mo Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.po -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -1,13 +1,13 @@
2
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
 # This file is distributed under the same license as the PACKAGE package.
4
 #
5
-# Pavel Fric <pavelfric@seznam.cz>, 2013, 2014, 2015.
6
+# Pavel Fric <pavelfric@seznam.cz>, 2013, 2014, 2015, 2016.
7
 msgid ""
8
 msgstr ""
9
 "Project-Id-Version: \n"
10
 "Report-Msgid-Bugs-To: \n"
11
-"POT-Creation-Date: 2015-11-23 20:30+0200\n"
12
-"PO-Revision-Date: 2015-11-07 13:11+0100\n"
13
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
14
+"PO-Revision-Date: 2016-03-05 13:35+0100\n"
15
 "Last-Translator: Pavel Fric <pavelfric@seznam.cz>\n"
16
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
17
 "Language: cs\n"
18
@@ -19,84 +19,89 @@
19
 "X-Language: cs_CZ\n"
20
 "X-Source-Language: C\n"
21
 
22
-#: app.py:685
23
+#: app.py:733
24
 msgid "Too small screen for this application."
25
 msgstr "Příliš malá obrazovka pro tento program."
26
 
27
-#: app.py:688
28
+#: app.py:736
29
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
30
 msgstr "Nejmenší rozměry obrazovky pro tento program jsou 1152 x 768.\n"
31
 
32
-#: app.py:689
33
+#: app.py:737
34
 msgid "Your screen dimensions are "
35
 msgstr "Rozměry vaší obrazovky jsou "
36
 
37
-#: app.py:724
38
+#: app.py:761
39
 msgid "Project has not been saved since it was opened."
40
 msgstr "Projekt nebyl od té doby, co byl otevřen, uložen."
41
 
42
-#: app.py:729
43
+#: app.py:766
44
 msgid "Project was saved less than a minute ago."
45
 msgstr "Projekt byl uložen před méně než minutou."
46
 
47
-#: app.py:732
48
+#: app.py:769
49
 msgid "Project was saved one minute ago."
50
 msgstr "Projekt byl uložen před jednou minutou."
51
 
52
-#: app.py:734
53
+#: app.py:771
54
 msgid "Project was saved "
55
 msgstr "Projekt byl uložen před "
56
 
57
-#: app.py:734
58
+#: app.py:771
59
 msgid " minutes ago."
60
 msgstr " minutami"
61
 
62
-#: app.py:744 projectaction.py:278
63
+#: app.py:781 projectaction.py:327
64
 msgid "Project has not been saved previously"
65
 msgstr "Projekt předtím byl uložen"
66
 
67
-#: app.py:745 projectaction.py:279
68
+#: app.py:782 projectaction.py:328
69
 msgid "Save project with File -> Save As before closing."
70
 msgstr "Uložte projekt před zavření pomocí Soubor -> Uložit."
71
 
72
-#: projectaction.py:106
73
+#: projectaction.py:111
74
 msgid "Media asset was missing!"
75
 msgstr "Položka záznamů chybí!"
76
 
77
-#: projectaction.py:107
78
+#: projectaction.py:112
79
 msgid "Path of missing asset:"
80
 msgstr "Cesta k chybějící položce:"
81
 
82
-#: projectaction.py:108
83
+#: projectaction.py:113
84
 msgid ""
85
 "Relative search for replacement file in sub folders of project file failed."
86
 msgstr ""
87
 "Relativní hledání pro nahrazovací soubor v podsložkách souboru s projektem "
88
 "se nezdařilo."
89
 
90
-#: projectaction.py:109
91
+#: projectaction.py:114
92
 msgid "To load the project you will need to either:"
93
 msgstr "Pro nahrání projektu budete potřebovat:"
94
 
95
-#: projectaction.py:110
96
-msgid "Use 'Media Linker' tool to relink media assets to new files, or"
97
+#: projectaction.py:115
98
+msgid ""
99
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
100
 msgstr ""
101
-"Použijte spojovací program na záznamy pro opětovné spojení položek záznamů s "
102
-"novými soubory, nebo"
103
+"Otevřít projekt v nástroji Znovuspojovač záznamů pro opětovné spojení "
104
+"položek záznamů s novými soubory, nebo"
105
 
106
-#: projectaction.py:111
107
+#: projectaction.py:116
108
 msgid "Place a file with the same exact name and path on the hard drive"
109
 msgstr "Umístěte falešný soubor s přesně stejným názvem a cestou na pevný disk"
110
 
111
-#: projectaction.py:118
112
+#: projectaction.py:117
113
+msgid "Open project in Media Relinker tool"
114
+msgstr "Otevřít projekt v nástroji Znovuspojovač záznamů"
115
+
116
+#: projectaction.py:136
117
 msgid "Profile with Description: '"
118
 msgstr "Profil s popisem: "
119
 
120
-#: projectaction.py:118
121
+#: projectaction.py:136
122
 msgid "' was not found on load!"
123
 msgstr " nebyl při nahrávání nalezen!"
124
 
125
-#: projectaction.py:119
126
+#: projectaction.py:137
127
 msgid ""
128
 "It is possible to load the project by creating a User Profile with exactly "
129
 "the same Description\n"
130
@@ -106,19 +111,19 @@
131
 "popisem\n"
132
 "jako má chybějící profil. "
133
 
134
-#: projectaction.py:120
135
+#: projectaction.py:138
136
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
137
 msgstr "Uživatelské profily lze vytvářet vybráním Úpravy -> Správce profilů."
138
 
139
-#: projectaction.py:127
140
+#: projectaction.py:145
141
 msgid "Opening"
142
 msgstr "Otevírá se"
143
 
144
-#: projectaction.py:210
145
+#: projectaction.py:238
146
 msgid "Media files already present in project were opened!"
147
 msgstr "Soubory již přítomné v projektu byly otevřeny!"
148
 
149
-#: projectaction.py:216
150
+#: projectaction.py:244
151
 msgid ""
152
 "Files already present:\n"
153
 "\n"
154
@@ -126,62 +131,62 @@
155
 "Soubory již přítomné:\n"
156
 "\n"
157
 
158
-#: projectaction.py:374
159
+#: projectaction.py:442
160
 msgid "Selected folder contains files"
161
 msgstr "Vybraná složka obsahuje soubory"
162
 
163
-#: projectaction.py:375
164
+#: projectaction.py:443
165
 msgid ""
166
 "When saving a back-up snapshot of the project, the selected folder\n"
167
 "has to be empty."
168
 msgstr ""
169
 "Při ukládání záložního snímku projektu musí být vybraná složka prázdná."
170
 
171
-#: projectaction.py:401
172
+#: projectaction.py:501
173
 msgid "Copying project media assets"
174
 msgstr "Kopírují se položky záznamů projektu"
175
 
176
-#: projectaction.py:402
177
+#: projectaction.py:502
178
 msgid "Saving project file"
179
 msgstr "Ukládá se soubor s projektem"
180
 
181
-#: projectaction.py:525
182
+#: projectaction.py:625
183
 msgid "Project not found on disk"
184
 msgstr "Projekt nebyl na disku nalezen"
185
 
186
-#: projectaction.py:526
187
+#: projectaction.py:626
188
 msgid "Project can't be loaded."
189
 msgstr "Projekt nelze nahrát."
190
 
191
-#: projectaction.py:583
192
+#: projectaction.py:684
193
 msgid "Render launch failed!"
194
 msgstr "Spuštění zpracování se nezdařilo!"
195
 
196
-#: projectaction.py:584 projectaction.py:598 tools/batchrendering.py:295
197
+#: projectaction.py:685 projectaction.py:699 tools/batchrendering.py:296
198
 msgid "Error message: "
199
 msgstr "Zpráva o chybě: "
200
 
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.mo -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.mo Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.po -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -1,13 +1,14 @@
2
-# Language de translations for PACKAGE package.
3
-# Copyright (C) 2014 THE PACKAGE'S COPYRIGHT HOLDER
4
-# This file is distributed under the same license as the PACKAGE package.
5
-# Martin Wielebinski <mwdev@esc.de>, 2014.
6
-#
7
+# Language de translations for PACKAGE package.
8
+# Copyright (C) 2014 THE PACKAGE'S COPYRIGHT HOLDER
9
+# This file is distributed under the same license as the PACKAGE package.
10
+# Martin Wielebinski <mwdev@esc.de>, 2014.
11
+# Adaptions by Bene81 <Bene81@users.noreply.github.com>
12
+# 
13
 msgid ""
14
 msgstr ""
15
 "Project-Id-Version: PACKAGE VERSION\n"
16
 "Report-Msgid-Bugs-To: \n"
17
-"POT-Creation-Date: 2015-11-23 20:30+0200\n"
18
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
19
 "PO-Revision-Date: 2014-11-23 14:22+0100\n"
20
 "Last-Translator: Martin Wielebinski <mwdev@esc.de>\n"
21
 "Language-Team: German\n"
22
@@ -17,102 +18,115 @@
23
 "Content-Transfer-Encoding: 8bit\n"
24
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
25
 
26
-#: app.py:685
27
+#: app.py:733
28
 msgid "Too small screen for this application."
29
 msgstr "Zu kleiner Bildschirm für diese Applikation."
30
 
31
-#: app.py:688
32
+#: app.py:736
33
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
34
 msgstr "Minimale Auflösung für diese Applikation ist 1152 x 768.\n"
35
 
36
-#: app.py:689
37
+#: app.py:737
38
 msgid "Your screen dimensions are "
39
 msgstr "Ihre Auflösung beträgt "
40
 
41
-#: app.py:724
42
+#: app.py:761
43
 msgid "Project has not been saved since it was opened."
44
 msgstr "Projekt wurde seit dem Öffnen nicht gesichert."
45
 
46
-#: app.py:729
47
+#: app.py:766
48
 msgid "Project was saved less than a minute ago."
49
 msgstr "Projekt wurde vor weniger als einer Minute gesichert."
50
 
51
-#: app.py:732
52
+#: app.py:769
53
 msgid "Project was saved one minute ago."
54
 msgstr "Projekt wurde vor einer Minute gesichert."
55
 
56
-#: app.py:734
57
+#: app.py:771
58
 msgid "Project was saved "
59
 msgstr "Projekt wurde vor "
60
 
61
-#: app.py:734
62
+#: app.py:771
63
 msgid " minutes ago."
64
 msgstr " Minuten gesichert."
65
 
66
-#: app.py:744 projectaction.py:278
67
+#: app.py:781 projectaction.py:327
68
 msgid "Project has not been saved previously"
69
-msgstr "Projekt wurde zuvor nicht gesichert"
70
+msgstr "Projekt wurde noch nicht gesichert"
71
 
72
-#: app.py:745 projectaction.py:279
73
+#: app.py:782 projectaction.py:328
74
 msgid "Save project with File -> Save As before closing."
75
-msgstr "Projekt vor dem Schließen sichern mit Datei -> Sichern als."
76
+msgstr "Projekt vor dem Schließen sichern mit 'Datei -> Sichern als...'."
77
 
78
-#: projectaction.py:106
79
+#: projectaction.py:111
80
 msgid "Media asset was missing!"
81
-msgstr ""
82
+msgstr "Mediendatei fehlt!"
83
 
84
-#: projectaction.py:107
85
+#: projectaction.py:112
86
 msgid "Path of missing asset:"
87
-msgstr ""
88
+msgstr "Pfad der fehlenden Datei:"
89
 
90
-#: projectaction.py:108
91
+#: projectaction.py:113
92
 msgid ""
93
 "Relative search for replacement file in sub folders of project file failed."
94
 msgstr ""
95
+"Relative Suche nach einem Ersatz in Unterverzeichnissen ist fehlgeschlagen."
96
 
97
-#: projectaction.py:109
98
+#: projectaction.py:114
99
 msgid "To load the project you will need to either:"
100
-msgstr ""
101
+msgstr "Um das Projekt zu laden ist einer der folgenden Schritte erforderlich:"
102
 
103
-#: projectaction.py:110
104
-msgid "Use 'Media Linker' tool to relink media assets to new files, or"
105
+#: projectaction.py:115
106
+#, fuzzy
107
+msgid ""
108
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
109
 msgstr ""
110
+"'Medien-Link'-Werkzeug nutzen, um Medien mit anderen Dateien zu verknüpfen, "
111
+"oder"
112
 
113
-#: projectaction.py:111
114
+#: projectaction.py:116
115
 #, fuzzy
116
 msgid "Place a file with the same exact name and path on the hard drive"
117
-msgstr "Ersatzdatei mit gleichem Namen und ähnlichem Inhalt anlegen,"
118
+msgstr "eine Ersatzdatei mit gleichem Namen und ähnlichem Inhalt anlegen"
119
+
120
+#: projectaction.py:117
121
+msgid "Open project in Media Relinker tool"
122
+msgstr ""
123
 
124
-#: projectaction.py:118
125
+#: projectaction.py:136
126
 #, fuzzy
127
 msgid "Profile with Description: '"
128
-msgstr "Beschreibung: "
129
+msgstr "Profil mit Beschreibung: '"
130
 
131
-#: projectaction.py:118
132
+#: projectaction.py:136
133
 #, fuzzy
134
 msgid "' was not found on load!"
135
-msgstr " wurde beim Laden nicht gefunden!"
136
+msgstr "' wurde beim Laden nicht gefunden!"
137
 
138
-#: projectaction.py:119
139
+#: projectaction.py:137
140
 msgid ""
141
 "It is possible to load the project by creating a User Profile with exactly "
142
 "the same Description\n"
143
 "as the missing profile. "
144
 msgstr ""
145
+"Es ist möglich das Projekt zu laden, indem ein Nutzerprofil mit exakt der "
146
+"gleichen Beschreibung\n"
147
+"wie das fehlende Profil angelegt wird. "
148
 
149
-#: projectaction.py:120
150
+#: projectaction.py:138
151
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
152
 msgstr ""
153
+"Nutzerprofile können unter 'Bearbeiten->Profil-Manager' angelegt werden."
154
 
155
-#: projectaction.py:127
156
+#: projectaction.py:145
157
 msgid "Opening"
158
 msgstr "Öffnen"
159
 
160
-#: projectaction.py:210
161
+#: projectaction.py:238
162
 msgid "Media files already present in project were opened!"
163
 msgstr "Im Projekt bereits vorhandene Mediendateien wurden geöffnet!"
164
 
165
-#: projectaction.py:216
166
+#: projectaction.py:244
167
 msgid ""
168
 "Files already present:\n"
169
 "\n"
170
@@ -120,104 +134,119 @@
171
 "Bereits vorhandene Dateien:\n"
172
 "\n"
173
 
174
-#: projectaction.py:374
175
+#: projectaction.py:442
176
 #, fuzzy
177
 msgid "Selected folder contains files"
178
-msgstr "Wähle Ordner für neue Miniaturen."
179
+msgstr "Gewählter Ordner enthält Dateien"
180
 
181
-#: projectaction.py:375
182
+#: projectaction.py:443
183
 msgid ""
184
 "When saving a back-up snapshot of the project, the selected folder\n"
185
 "has to be empty."
186
 msgstr ""
187
+"Für das Sichern einer Sicherungskopie muss der gewählte Ordner\n"
188
+"leer sein."
189
 
190
-#: projectaction.py:401
191
+#: projectaction.py:501
192
 msgid "Copying project media assets"
193
-msgstr ""
194
+msgstr "Kopiere Projektmediendaten"
195
 
196
-#: projectaction.py:402
197
+#: projectaction.py:502
198
 #, fuzzy
199
 msgid "Saving project file"
200
-msgstr "Sichere Projekt '"
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.mo -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.mo Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.po -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2015-11-23 20:30+0200\n"
6
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
7
 "PO-Revision-Date: 2014-02-21 12:08+0200\n"
8
 "Last-Translator: David Gámiz Jiménez <david.gamiz@gmail.com>\n"
9
 "Language-Team: David Gamiz Jimenez\n"
10
@@ -18,170 +18,175 @@
11
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
12
 "X-Generator: Virtaal 0.7.0\n"
13
 
14
-#: app.py:685
15
+#: app.py:733
16
 msgid "Too small screen for this application."
17
 msgstr "La pantalla es demasiado pequeña para esta aplicación."
18
 
19
-#: app.py:688
20
+#: app.py:736
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr ""
23
 "La dimensión de pantalla mínima para esta aplicación es de 1152 x 768.\n"
24
 
25
-#: app.py:689
26
+#: app.py:737
27
 msgid "Your screen dimensions are "
28
 msgstr "Las dimensiones de su pantalla son "
29
 
30
-#: app.py:724
31
+#: app.py:761
32
 msgid "Project has not been saved since it was opened."
33
 msgstr "El proyecto no ha sido salvado desde que se abrió."
34
 
35
-#: app.py:729
36
+#: app.py:766
37
 msgid "Project was saved less than a minute ago."
38
 msgstr "El proyecto fue salvado hace menos de un minuto."
39
 
40
-#: app.py:732
41
+#: app.py:769
42
 msgid "Project was saved one minute ago."
43
 msgstr "El proyecto fue salvado hace un minuto."
44
 
45
-#: app.py:734
46
+#: app.py:771
47
 msgid "Project was saved "
48
 msgstr "El proyecto salvado "
49
 
50
-#: app.py:734
51
+#: app.py:771
52
 msgid " minutes ago."
53
 msgstr " hace minutos."
54
 
55
-#: app.py:744 projectaction.py:278
56
+#: app.py:781 projectaction.py:327
57
 msgid "Project has not been saved previously"
58
 msgstr "El proyecto no se ha salvado antes"
59
 
60
-#: app.py:745 projectaction.py:279
61
+#: app.py:782 projectaction.py:328
62
 msgid "Save project with File -> Save As before closing."
63
 msgstr "Salvar el proyecto en un Archivo -> Salvar como antes de cerrar."
64
 
65
-#: projectaction.py:106
66
+#: projectaction.py:111
67
 msgid "Media asset was missing!"
68
 msgstr ""
69
 
70
-#: projectaction.py:107
71
+#: projectaction.py:112
72
 msgid "Path of missing asset:"
73
 msgstr ""
74
 
75
-#: projectaction.py:108
76
+#: projectaction.py:113
77
 msgid ""
78
 "Relative search for replacement file in sub folders of project file failed."
79
 msgstr ""
80
 
81
-#: projectaction.py:109
82
+#: projectaction.py:114
83
 msgid "To load the project you will need to either:"
84
 msgstr ""
85
 
86
-#: projectaction.py:110
87
-msgid "Use 'Media Linker' tool to relink media assets to new files, or"
88
+#: projectaction.py:115
89
+msgid ""
90
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
91
 msgstr ""
92
 
93
-#: projectaction.py:111
94
+#: projectaction.py:116
95
 #, fuzzy
96
 msgid "Place a file with the same exact name and path on the hard drive"
97
 msgstr ""
98
 "Coloque un archivo vacío con el mismo nombre y contenido similar para activar"
99
 
100
-#: projectaction.py:118
101
+#: projectaction.py:117
102
+msgid "Open project in Media Relinker tool"
103
+msgstr ""
104
+
105
+#: projectaction.py:136
106
 #, fuzzy
107
 msgid "Profile with Description: '"
108
 msgstr "Descripción:"
109
 
110
-#: projectaction.py:118
111
+#: projectaction.py:136
112
 #, fuzzy
113
 msgid "' was not found on load!"
114
 msgstr " ¡no se ha encontrado en la carga!"
115
 
116
-#: projectaction.py:119
117
+#: projectaction.py:137
118
 msgid ""
119
 "It is possible to load the project by creating a User Profile with exactly "
120
 "the same Description\n"
121
 "as the missing profile. "
122
 msgstr ""
123
 
124
-#: projectaction.py:120
125
+#: projectaction.py:138
126
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
127
 msgstr ""
128
 
129
-#: projectaction.py:127
130
+#: projectaction.py:145
131
 msgid "Opening"
132
 msgstr "Abriendo"
133
 
134
-#: projectaction.py:210
135
+#: projectaction.py:238
136
 msgid "Media files already present in project were opened!"
137
 msgstr ""
138
 
139
-#: projectaction.py:216
140
+#: projectaction.py:244
141
 #, fuzzy
142
 msgid ""
143
 "Files already present:\n"
144
 "\n"
145
 msgstr " ya existe!"
146
 
147
-#: projectaction.py:374
148
+#: projectaction.py:442
149
 #, fuzzy
150
 msgid "Selected folder contains files"
151
 msgstr "Seleccionar carpeta para nuevos miniaturas."
152
 
153
-#: projectaction.py:375
154
+#: projectaction.py:443
155
 msgid ""
156
 "When saving a back-up snapshot of the project, the selected folder\n"
157
 "has to be empty."
158
 msgstr ""
159
 
160
-#: projectaction.py:401
161
+#: projectaction.py:501
162
 msgid "Copying project media assets"
163
 msgstr ""
164
 
165
-#: projectaction.py:402
166
+#: projectaction.py:502
167
 #, fuzzy
168
 msgid "Saving project file"
169
 msgstr "¿Guardar proyecto '"
170
 
171
-#: projectaction.py:525
172
+#: projectaction.py:625
173
 msgid "Project not found on disk"
174
 msgstr "El proyecto no se encuentra en el disco"
175
 
176
-#: projectaction.py:526
177
+#: projectaction.py:626
178
 msgid "Project can't be loaded."
179
 msgstr "El proyecto no puede ser cargado."
180
 
181
-#: projectaction.py:583
182
+#: projectaction.py:684
183
 #, fuzzy
184
 msgid "Render launch failed!"
185
 msgstr "Render rango no definido!"
186
 
187
-#: projectaction.py:584 projectaction.py:598 tools/batchrendering.py:295
188
+#: projectaction.py:685 projectaction.py:699 tools/batchrendering.py:296
189
 msgid "Error message: "
190
 msgstr "Mensaje de error:"
191
 
192
-#: projectaction.py:597
193
+#: projectaction.py:698
194
 msgid "Adding item to render queue failed!"
195
 msgstr "¡Fallo al añadir un elemento a la cola de renderizado!"
196
 
197
-#: projectaction.py:616
198
+#: projectaction.py:717
199
 msgid "Open.."
200
 msgstr "Abrir…"
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.mo -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.mo Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.po -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2015-11-23 20:30+0200\n"
6
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
7
 "PO-Revision-Date: 2011-12-13 23:55+0200\n"
8
 "Last-Translator: Janne Liljeblad <janne@janne-kx557aa-uuw-a6521-sc>\n"
9
 "Language-Team: Finnish\n"
10
@@ -17,82 +17,87 @@
11
 "Content-Transfer-Encoding: 8bit\n"
12
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
 
14
-#: app.py:685
15
+#: app.py:733
16
 msgid "Too small screen for this application."
17
 msgstr "Näyttö on liian pieni tälle ohjelmalle."
18
 
19
-#: app.py:688
20
+#: app.py:736
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr "Minimi näyttökoko tällle ohjelmalle on 1152 x 768.\n"
23
 
24
-#: app.py:689
25
+#: app.py:737
26
 msgid "Your screen dimensions are "
27
 msgstr "Sinun näyttösi koko on "
28
 
29
-#: app.py:724
30
+#: app.py:761
31
 msgid "Project has not been saved since it was opened."
32
 msgstr "Projektia ei ole tallennettu aikaisemmin."
33
 
34
-#: app.py:729
35
+#: app.py:766
36
 msgid "Project was saved less than a minute ago."
37
 msgstr "Projekti tallennettiin viimeksi alle minuutti sitten."
38
 
39
-#: app.py:732
40
+#: app.py:769
41
 msgid "Project was saved one minute ago."
42
 msgstr "Projekti tallennettiin viimeksi minuutti sitten."
43
 
44
-#: app.py:734
45
+#: app.py:771
46
 msgid "Project was saved "
47
 msgstr "Projektia ei ole tallennettu aikaisemmin"
48
 
49
-#: app.py:734
50
+#: app.py:771
51
 msgid " minutes ago."
52
 msgstr " minuuttia sitten."
53
 
54
-#: app.py:744 projectaction.py:278
55
+#: app.py:781 projectaction.py:327
56
 msgid "Project has not been saved previously"
57
 msgstr "Projektia ei ole tallennettu aikaisemmin"
58
 
59
-#: app.py:745 projectaction.py:279
60
+#: app.py:782 projectaction.py:328
61
 msgid "Save project with File -> Save As before closing."
62
 msgstr ""
63
 "Tallenna projekti valinnalla Tiedosto -> Tallenna nimellä ennen sulkemista."
64
 
65
-#: projectaction.py:106
66
+#: projectaction.py:111
67
 msgid "Media asset was missing!"
68
 msgstr ""
69
 
70
-#: projectaction.py:107
71
+#: projectaction.py:112
72
 msgid "Path of missing asset:"
73
 msgstr ""
74
 
75
-#: projectaction.py:108
76
+#: projectaction.py:113
77
 msgid ""
78
 "Relative search for replacement file in sub folders of project file failed."
79
 msgstr ""
80
 
81
-#: projectaction.py:109
82
+#: projectaction.py:114
83
 msgid "To load the project you will need to either:"
84
 msgstr ""
85
 
86
-#: projectaction.py:110
87
-msgid "Use 'Media Linker' tool to relink media assets to new files, or"
88
+#: projectaction.py:115
89
+msgid ""
90
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
91
 msgstr ""
92
 
93
-#: projectaction.py:111
94
+#: projectaction.py:116
95
 msgid "Place a file with the same exact name and path on the hard drive"
96
 msgstr ""
97
 "Aseta samaan paikkaan samanniminen ja tyyppinen tiedosto mahdollistaaksesi"
98
 
99
-#: projectaction.py:118
100
+#: projectaction.py:117
101
+msgid "Open project in Media Relinker tool"
102
+msgstr ""
103
+
104
+#: projectaction.py:136
105
 msgid "Profile with Description: '"
106
 msgstr "Priilia, jolla on kuvaus:"
107
 
108
-#: projectaction.py:118
109
+#: projectaction.py:136
110
 msgid "' was not found on load!"
111
 msgstr " ei löytynyt ladattaessa!"
112
 
113
-#: projectaction.py:119
114
+#: projectaction.py:137
115
 msgid ""
116
 "It is possible to load the project by creating a User Profile with exactly "
117
 "the same Description\n"
118
@@ -102,19 +107,19 @@
119
 "nimi kuin\n"
120
 "puuttuvalla profiililla."
121
 
122
-#: projectaction.py:120
123
+#: projectaction.py:138
124
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
125
 msgstr ""
126
 
127
-#: projectaction.py:127
128
+#: projectaction.py:145
129
 msgid "Opening"
130
 msgstr "Avaa"
131
 
132
-#: projectaction.py:210
133
+#: projectaction.py:238
134
 msgid "Media files already present in project were opened!"
135
 msgstr "Avattiin media tiedostoja, jotka jo ovat projektissa"
136
 
137
-#: projectaction.py:216
138
+#: projectaction.py:244
139
 msgid ""
140
 "Files already present:\n"
141
 "\n"
142
@@ -122,11 +127,11 @@
143
 "Projektissa jo olevat tiedostot:\n"
144
 "\n"
145
 
146
-#: projectaction.py:374
147
+#: projectaction.py:442
148
 msgid "Selected folder contains files"
149
 msgstr "Valitussa kansiossa on tiedostoja"
150
 
151
-#: projectaction.py:375
152
+#: projectaction.py:443
153
 msgid ""
154
 "When saving a back-up snapshot of the project, the selected folder\n"
155
 "has to be empty."
156
@@ -134,52 +139,52 @@
157
 "Kun tallennetaan projektia ja mediaa yhtä aikaa\n"
158
 "täytyy kansion olla tyhjä."
159
 
160
-#: projectaction.py:401
161
+#: projectaction.py:501
162
 msgid "Copying project media assets"
163
 msgstr "Kopioidaan mediaa"
164
 
165
-#: projectaction.py:402
166
+#: projectaction.py:502
167
 msgid "Saving project file"
168
 msgstr "Tallennetaan projektia"
169
 
170
-#: projectaction.py:525
171
+#: projectaction.py:625
172
 msgid "Project not found on disk"
173
 msgstr "Projektia ei löytynyt kovalevyltä"
174
 
175
-#: projectaction.py:526
176
+#: projectaction.py:626
177
 msgid "Project can't be loaded."
178
 msgstr "Projektia ei voida ladata."
179
 
180
-#: projectaction.py:583
181
+#: projectaction.py:684
182
 #, fuzzy
183
 msgid "Render launch failed!"
184
 msgstr "Renderöinti alue ei ole määritelty"
185
 
186
-#: projectaction.py:584 projectaction.py:598 tools/batchrendering.py:295
187
+#: projectaction.py:685 projectaction.py:699 tools/batchrendering.py:296
188
 msgid "Error message: "
189
 msgstr "Virhe viesti"
190
 
191
-#: projectaction.py:597
192
+#: projectaction.py:698
193
 msgid "Adding item to render queue failed!"
194
 msgstr ""
195
 
196
-#: projectaction.py:616
197
+#: projectaction.py:717
198
 msgid "Open.."
199
 msgstr "Avaa"
200
 
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.mo -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.mo Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.po -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2015-11-23 20:30+0200\n"
6
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
7
 "PO-Revision-Date: 2013-09-20 18:54+0200\n"
8
 "Last-Translator: Loïc Vanderstichelen <lv@loicvanderstichelen.com>\n"
9
 "Language-Team: French\n"
10
@@ -17,169 +17,174 @@
11
 "Content-Transfer-Encoding: 8bit\n"
12
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
13
 
14
-#: app.py:685
15
+#: app.py:733
16
 msgid "Too small screen for this application."
17
 msgstr "Votre écran est trop petit pour cette application."
18
 
19
-#: app.py:688
20
+#: app.py:736
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr "La résolution minimum pour cet application est de 1152 x 768.\n"
23
 
24
-#: app.py:689
25
+#: app.py:737
26
 msgid "Your screen dimensions are "
27
 msgstr "Votre résolution actuelle est "
28
 
29
-#: app.py:724
30
+#: app.py:761
31
 msgid "Project has not been saved since it was opened."
32
 msgstr "Ce projet n'a pas été enregistré depuis qu'il a été ouvert."
33
 
34
-#: app.py:729
35
+#: app.py:766
36
 msgid "Project was saved less than a minute ago."
37
 msgstr "Le projet a été sauvegardé il y a moins d'une minute."
38
 
39
-#: app.py:732
40
+#: app.py:769
41
 msgid "Project was saved one minute ago."
42
 msgstr "Le projet a été sauvegardé il y a une minute."
43
 
44
-#: app.py:734
45
+#: app.py:771
46
 msgid "Project was saved "
47
 msgstr "Le projet a été sauvegardé il y a "
48
 
49
-#: app.py:734
50
+#: app.py:771
51
 msgid " minutes ago."
52
 msgstr " minutes."
53
 
54
-#: app.py:744 projectaction.py:278
55
+#: app.py:781 projectaction.py:327
56
 msgid "Project has not been saved previously"
57
 msgstr "Le projet n'a jamais été sauvegardé"
58
 
59
-#: app.py:745 projectaction.py:279
60
+#: app.py:782 projectaction.py:328
61
 msgid "Save project with File -> Save As before closing."
62
 msgstr "Sauvegardez le projet avec Fichier -> Enregistrer sous."
63
 
64
-#: projectaction.py:106
65
+#: projectaction.py:111
66
 msgid "Media asset was missing!"
67
 msgstr ""
68
 
69
-#: projectaction.py:107
70
+#: projectaction.py:112
71
 msgid "Path of missing asset:"
72
 msgstr ""
73
 
74
-#: projectaction.py:108
75
+#: projectaction.py:113
76
 msgid ""
77
 "Relative search for replacement file in sub folders of project file failed."
78
 msgstr ""
79
 
80
-#: projectaction.py:109
81
+#: projectaction.py:114
82
 msgid "To load the project you will need to either:"
83
 msgstr ""
84
 
85
-#: projectaction.py:110
86
-msgid "Use 'Media Linker' tool to relink media assets to new files, or"
87
+#: projectaction.py:115
88
+msgid ""
89
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
90
 msgstr ""
91
 
92
-#: projectaction.py:111
93
+#: projectaction.py:116
94
 #, fuzzy
95
 msgid "Place a file with the same exact name and path on the hard drive"
96
 msgstr "Créez un fichier de même nom au contenu similaire pour pouvoir"
97
 
98
-#: projectaction.py:118
99
+#: projectaction.py:117
100
+msgid "Open project in Media Relinker tool"
101
+msgstr ""
102
+
103
+#: projectaction.py:136
104
 #, fuzzy
105
 msgid "Profile with Description: '"
106
 msgstr "Description:"
107
 
108
-#: projectaction.py:118
109
+#: projectaction.py:136
110
 #, fuzzy
111
 msgid "' was not found on load!"
112
 msgstr " n'a pas été trouvé!"
113
 
114
-#: projectaction.py:119
115
+#: projectaction.py:137
116
 msgid ""
117
 "It is possible to load the project by creating a User Profile with exactly "
118
 "the same Description\n"
119
 "as the missing profile. "
120
 msgstr ""
121
 
122
-#: projectaction.py:120
123
+#: projectaction.py:138
124
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
125
 msgstr ""
126
 
127
-#: projectaction.py:127
128
+#: projectaction.py:145
129
 msgid "Opening"
130
 msgstr "Ouverture"
131
 
132
-#: projectaction.py:210
133
+#: projectaction.py:238
134
 msgid "Media files already present in project were opened!"
135
 msgstr ""
136
 
137
-#: projectaction.py:216
138
+#: projectaction.py:244
139
 #, fuzzy
140
 msgid ""
141
 "Files already present:\n"
142
 "\n"
143
 msgstr " existe déjà!"
144
 
145
-#: projectaction.py:374
146
+#: projectaction.py:442
147
 #, fuzzy
148
 msgid "Selected folder contains files"
149
 msgstr "Sélectionner un dossier pour les nouvelles miniatures"
150
 
151
-#: projectaction.py:375
152
+#: projectaction.py:443
153
 msgid ""
154
 "When saving a back-up snapshot of the project, the selected folder\n"
155
 "has to be empty."
156
 msgstr ""
157
 
158
-#: projectaction.py:401
159
+#: projectaction.py:501
160
 msgid "Copying project media assets"
161
 msgstr ""
162
 
163
-#: projectaction.py:402
164
+#: projectaction.py:502
165
 #, fuzzy
166
 msgid "Saving project file"
167
 msgstr "Sauvegarder le projet '"
168
 
169
-#: projectaction.py:525
170
+#: projectaction.py:625
171
 msgid "Project not found on disk"
172
 msgstr "Le projet n'a pas été trouvé sur le disque"
173
 
174
-#: projectaction.py:526
175
+#: projectaction.py:626
176
 msgid "Project can't be loaded."
177
 msgstr "Le projet ne peut pas être chargé."
178
 
179
-#: projectaction.py:583
180
+#: projectaction.py:684
181
 #, fuzzy
182
 msgid "Render launch failed!"
183
 msgstr "Zone de rendu non définie!"
184
 
185
-#: projectaction.py:584 projectaction.py:598 tools/batchrendering.py:295
186
+#: projectaction.py:685 projectaction.py:699 tools/batchrendering.py:296
187
 #, fuzzy
188
 msgid "Error message: "
189
 msgstr "Message d'erreur: "
190
 
191
-#: projectaction.py:597
192
+#: projectaction.py:698
193
 msgid "Adding item to render queue failed!"
194
 msgstr "Echec de l'ajout d'élément à la liste de rendu!"
195
 
196
-#: projectaction.py:616
197
+#: projectaction.py:717
198
 msgid "Open.."
199
 msgstr "Ouvrir..."
200
 
201
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/hu Added
2
 
1
+(directory)
2
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES Added
2
 
1
+(directory)
2
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.mo Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.po Added
201
 
1
@@ -0,0 +1,5820 @@
2
+# Hungarian translations for PACKAGE package.
3
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
4
+# This file is distributed under the same license as the PACKAGE package.
5
+# Péter Gábor <ptrg@freemail.hu>, 2015.
6
+#
7
+msgid ""
8
+msgstr ""
9
+"Project-Id-Version: \n"
10
+"Report-Msgid-Bugs-To: \n"
11
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
12
+"PO-Revision-Date: 2016-08-04 21:35+0100\n"
13
+"Last-Translator: Péter Gábor <ptrg@freemail.hu>\n"
14
+"Language-Team: \n"
15
+"Language: hu-HU\n"
16
+"MIME-Version: 1.0\n"
17
+"Content-Type: text/plain; charset=UTF-8\n"
18
+"Content-Transfer-Encoding: 8bit\n"
19
+"X-Generator: Poedit 1.5.4\n"
20
+
21
+#: app.py:733
22
+msgid "Too small screen for this application."
23
+msgstr "Túl kicsi a képernyő az alkalmazás számára."
24
+
25
+#: app.py:736
26
+msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
27
+msgstr "A minimális képernyőfelbontás ezen alkalmazás számára 1152 x 768.\n"
28
+
29
+#: app.py:737
30
+msgid "Your screen dimensions are "
31
+msgstr "Az ön képernyőjének felbontása "
32
+
33
+#: app.py:761
34
+msgid "Project has not been saved since it was opened."
35
+msgstr "A projekt még nem volt mentve a megnyitás óta."
36
+
37
+#: app.py:766
38
+msgid "Project was saved less than a minute ago."
39
+msgstr "A projekt kevesebb mint egy perce volt mentve"
40
+
41
+#: app.py:769
42
+msgid "Project was saved one minute ago."
43
+msgstr "A projekt egy perce volt mentve."
44
+
45
+#: app.py:771
46
+msgid "Project was saved "
47
+msgstr "A projekt mentése "
48
+
49
+#: app.py:771
50
+msgid " minutes ago."
51
+msgstr " perce történt."
52
+
53
+#: app.py:781 projectaction.py:327
54
+msgid "Project has not been saved previously"
55
+msgstr "A projekt korábban még nem volt mentve"
56
+
57
+#: app.py:782 projectaction.py:328
58
+msgid "Save project with File -> Save As before closing."
59
+msgstr ""
60
+"Mentse a projektet a Fájl -> Mentés másként menüpont használatával mielőtt "
61
+"bezárná."
62
+
63
+#: projectaction.py:111
64
+msgid "Media asset was missing!"
65
+msgstr "Hiányzó média összetevő!"
66
+
67
+#: projectaction.py:112
68
+msgid "Path of missing asset:"
69
+msgstr "A hiányzó média összetevő útvonala:"
70
+
71
+#: projectaction.py:113
72
+msgid ""
73
+"Relative search for replacement file in sub folders of project file failed."
74
+msgstr ""
75
+"A keresés a relatív útvonalakon a projekt almappáiban nem járt sikerrel."
76
+
77
+#: projectaction.py:114
78
+msgid "To load the project you will need to either:"
79
+msgstr "A projekt betöltéséhez szükség van a következők valamelyikére:"
80
+
81
+#: projectaction.py:115
82
+msgid ""
83
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
84
+msgstr ""
85
+"Projekt megnyitása a 'Média újracsatoló' eszközben a média összetevők "
86
+"újracsatolásához, vagy"
87
+
88
+#: projectaction.py:116
89
+msgid "Place a file with the same exact name and path on the hard drive"
90
+msgstr ""
91
+"Helyezzen el egy fájlt teljesen megegyező névvel és útvonallal a meghajtón"
92
+
93
+#: projectaction.py:117
94
+msgid "Open project in Media Relinker tool"
95
+msgstr "Projekt megnyitása a 'Média újracsatoló' eszközben"
96
+
97
+#: projectaction.py:136
98
+msgid "Profile with Description: '"
99
+msgstr "A profil ezzel a leírással: '"
100
+
101
+#: projectaction.py:136
102
+msgid "' was not found on load!"
103
+msgstr "' nem volt a megtalálható betöltés során!"
104
+
105
+#: projectaction.py:137
106
+msgid ""
107
+"It is possible to load the project by creating a User Profile with exactly "
108
+"the same Description\n"
109
+"as the missing profile. "
110
+msgstr ""
111
+"Betölthető a projekt egy a hiányzóval profillal teljesen megegyező leírást "
112
+"tartalmazó\n"
113
+"felhasználói profil létrehozása után."
114
+
115
+#: projectaction.py:138
116
+msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
117
+msgstr ""
118
+"Felhasználói profilok létrehozhatók a 'Szerkesztés -> Profilkezelő' "
119
+"használatával."
120
+
121
+#: projectaction.py:145
122
+msgid "Opening"
123
+msgstr "Megnyitás"
124
+
125
+#: projectaction.py:238
126
+msgid "Media files already present in project were opened!"
127
+msgstr "A projektben már jelenlévő fájlok lettek megnyitva!"
128
+
129
+#: projectaction.py:244
130
+msgid ""
131
+"Files already present:\n"
132
+"\n"
133
+msgstr ""
134
+"Már jelenlévő fájlok:\n"
135
+"\n"
136
+
137
+#: projectaction.py:442
138
+msgid "Selected folder contains files"
139
+msgstr "A választott könyvtár fájlokat tartalmaz"
140
+
141
+#: projectaction.py:443
142
+msgid ""
143
+"When saving a back-up snapshot of the project, the selected folder\n"
144
+"has to be empty."
145
+msgstr ""
146
+"Egy projekt állapotának mentésekor a választott mappának\n"
147
+"üresnek kell lennie."
148
+
149
+#: projectaction.py:501
150
+msgid "Copying project media assets"
151
+msgstr "A projekt média összetevőinek másolása"
152
+
153
+#: projectaction.py:502
154
+msgid "Saving project file"
155
+msgstr "Projekt fájl mentése"
156
+
157
+#: projectaction.py:625
158
+msgid "Project not found on disk"
159
+msgstr "A projekt nem található a lemezen"
160
+
161
+#: projectaction.py:626
162
+msgid "Project can't be loaded."
163
+msgstr "A projekt nem tölthető be."
164
+
165
+#: projectaction.py:684
166
+msgid "Render launch failed!"
167
+msgstr "Nem sikerült elindítani a renderelést!"
168
+
169
+#: projectaction.py:685 projectaction.py:699 tools/batchrendering.py:296
170
+msgid "Error message: "
171
+msgstr "Hibaüzenet: "
172
+
173
+#: projectaction.py:698
174
+msgid "Adding item to render queue failed!"
175
+msgstr "Nem sikerült hozzáadni az elemet a renderelés várólistájához!"
176
+
177
+#: projectaction.py:717
178
+msgid "Open.."
179
+msgstr "Megnyitás..."
180
+
181
+#: projectaction.py:747
182
+msgid "No file was selected"
183
+msgstr "Nem lett fájl kiválasztva"
184
+
185
+#: projectaction.py:747
186
+msgid "Select a numbered file to add an Image Sequence to Project."
187
+msgstr ""
188
+"Válasszon egy sorszámozott fájlt, hogy képsorozatot adjon a projekthez."
189
+
190
+#: projectaction.py:755
191
+msgid "Not a sequence file!"
192
+msgstr "Nem jelenetfájl!"
193
+
194
+#: projectaction.py:755
195
+msgid ""
196
+"Selected file does not have a number part in it,\n"
197
+"so it can't be an image sequence file."
198
+msgstr ""
199
+"A kiválasztott fájl nem tartalmaz számot a nevében,\n"
200
+"így nem is lehet képsorozat része."
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.mo -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.mo Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.po -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: Floblade Italian Translation 0.14\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2015-11-23 20:30+0200\n"
6
+"POT-Creation-Date: 2016-09-15 21:26+0300\n"
7
 "PO-Revision-Date: 2014-09-15 23:42+0100\n"
8
 "Last-Translator: Massimo Stella <info@massimostella.it>\n"
9
 "Language-Team: Italiano\n"
10
@@ -18,102 +18,107 @@
11
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
12
 "X-Generator: Poedit 1.5.4\n"
13
 
14
-#: app.py:685
15
+#: app.py:733
16
 msgid "Too small screen for this application."
17
 msgstr "Lo schermo è troppo piccolo per questa applicazione."
18
 
19
-#: app.py:688
20
+#: app.py:736
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr "La risoluzione minima per questa applicazione è 1152 x 768.\n"
23
 
24
-#: app.py:689
25
+#: app.py:737
26
 msgid "Your screen dimensions are "
27
 msgstr "La risoluzione corrente è"
28
 
29
-#: app.py:724
30
+#: app.py:761
31
 msgid "Project has not been saved since it was opened."
32
 msgstr "Questo progetto non è ancora stato salvato dall'apertura."
33
 
34
-#: app.py:729
35
+#: app.py:766
36
 msgid "Project was saved less than a minute ago."
37
 msgstr "Il progetto è stato salvato meno di un minuto fa."
38
 
39
-#: app.py:732
40
+#: app.py:769
41
 msgid "Project was saved one minute ago."
42
 msgstr "Il progetto è stato salvato un minuto fa."
43
 
44
-#: app.py:734
45
+#: app.py:771
46
 msgid "Project was saved "
47
 msgstr "Il progetto è stato salvato"
48
 
49
-#: app.py:734
50
+#: app.py:771
51
 msgid " minutes ago."
52
 msgstr " minuti fa."
53
 
54
-#: app.py:744 projectaction.py:278
55
+#: app.py:781 projectaction.py:327
56
 msgid "Project has not been saved previously"
57
 msgstr "Il progetto non è mai stato salvato"
58
 
59
-#: app.py:745 projectaction.py:279
60
+#: app.py:782 projectaction.py:328
61
 msgid "Save project with File -> Save As before closing."
62
 msgstr "Salva il progetto da File -> Salva con nome"
63
 
64
-#: projectaction.py:106
65
+#: projectaction.py:111
66
 msgid "Media asset was missing!"
67
 msgstr ""
68
 
69
-#: projectaction.py:107
70
+#: projectaction.py:112
71
 msgid "Path of missing asset:"
72
 msgstr ""
73
 
74
-#: projectaction.py:108
75
+#: projectaction.py:113
76
 msgid ""
77
 "Relative search for replacement file in sub folders of project file failed."
78
 msgstr ""
79
 
80
-#: projectaction.py:109
81
+#: projectaction.py:114
82
 msgid "To load the project you will need to either:"
83
 msgstr ""
84
 
85
-#: projectaction.py:110
86
-msgid "Use 'Media Linker' tool to relink media assets to new files, or"
87
+#: projectaction.py:115
88
+msgid ""
89
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
90
 msgstr ""
91
 
92
-#: projectaction.py:111
93
+#: projectaction.py:116
94
 #, fuzzy
95
 msgid "Place a file with the same exact name and path on the hard drive"
96
 msgstr "Crea un file con lo stesso nome con contenuti simili per poter "
97
 
98
-#: projectaction.py:118
99
+#: projectaction.py:117
100
+msgid "Open project in Media Relinker tool"
101
+msgstr ""
102
+
103
+#: projectaction.py:136
104
 #, fuzzy
105
 msgid "Profile with Description: '"
106
 msgstr "Descrizione:"
107
 
108
-#: projectaction.py:118
109
+#: projectaction.py:136
110
 #, fuzzy
111
 msgid "' was not found on load!"
112
 msgstr "non è stato trovato!"
113
 
114
-#: projectaction.py:119
115
+#: projectaction.py:137
116
 msgid ""
117
 "It is possible to load the project by creating a User Profile with exactly "
118
 "the same Description\n"
119
 "as the missing profile. "
120
 msgstr ""
121
 
122
-#: projectaction.py:120
123
+#: projectaction.py:138
124
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
125
 msgstr ""
126
 
127
-#: projectaction.py:127
128
+#: projectaction.py:145
129
 msgid "Opening"
130
 msgstr "Apertura"
131
 
132
-#: projectaction.py:210
133
+#: projectaction.py:238
134
 msgid "Media files already present in project were opened!"
135
 msgstr "File multimediali già presenti nel progetto sono stati aperti!"
136
 
137
-#: projectaction.py:216
138
+#: projectaction.py:244
139
 msgid ""
140
 "Files already present:\n"
141
 "\n"
142
@@ -121,64 +126,64 @@
143
 "File già esistenti:\n"
144
 "\n"
145
 
146
-#: projectaction.py:374
147
+#: projectaction.py:442
148
 #, fuzzy
149
 msgid "Selected folder contains files"
150
 msgstr "Seleziona cartella per le nuove miniature."
151
 
152
-#: projectaction.py:375
153
+#: projectaction.py:443
154
 msgid ""
155
 "When saving a back-up snapshot of the project, the selected folder\n"
156
 "has to be empty."
157
 msgstr ""
158
 
159
-#: projectaction.py:401
160
+#: projectaction.py:501
161
 msgid "Copying project media assets"
162
 msgstr ""
163
 
164
-#: projectaction.py:402
165
+#: projectaction.py:502
166
 #, fuzzy
167
 msgid "Saving project file"
168
 msgstr "Salvo il progetto '"
169
 
170
-#: projectaction.py:525
171
+#: projectaction.py:625
172
 msgid "Project not found on disk"
173
 msgstr "Il progetto non è stato trovato sul disco"
174
 
175
-#: projectaction.py:526
176
+#: projectaction.py:626
177
 msgid "Project can't be loaded."
178
 msgstr "Il progetto non può essere caricato."
179
 
180
-#: projectaction.py:583
181
+#: projectaction.py:684
182
 #, fuzzy
183
 msgid "Render launch failed!"
184
 msgstr "Area di calcolo non definita!"
185
 
186
-#: projectaction.py:584 projectaction.py:598 tools/batchrendering.py:295
187
+#: projectaction.py:685 projectaction.py:699 tools/batchrendering.py:296
188
 msgid "Error message: "
189
 msgstr "Messaggio d'errore: "
190
 
191
-#: projectaction.py:597
192
+#: projectaction.py:698
193
 msgid "Adding item to render queue failed!"
194
 msgstr "Aggiunta alla coda dei render fallita!"
195
 
196
-#: projectaction.py:616
197
+#: projectaction.py:717
198
 msgid "Open.."
199
 msgstr "Apri..."
200
 
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/locale/upgrade_all -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/locale/upgrade_all Changed
9
 
1
@@ -1,6 +1,6 @@
2
 #/usr/bin/bash
3
 
4
-LANGUAGES=("fi" "cs" "fr" "es" "it" "de")
5
+LANGUAGES=("fi" "cs" "fr" "es" "it" "de" "hu")
6
 
7
 echo "Upgading all languages"
8
 
9
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/medialinker.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/medialinker.py Changed
86
 
1
@@ -53,11 +53,12 @@
2
 target_project = None
3
 media_assets = []
4
 
5
+NO_PROJECT_AT_LAUNCH = "##&&noproject&&##"
6
 
7
-def display_linker():
8
+def display_linker(filename=NO_PROJECT_AT_LAUNCH):
9
     print "Launching Media Re-linker"
10
     FLOG = open(utils.get_hidden_user_dir_path() + "log_media_relinker", 'w')
11
-    subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowblademedialinker"], stdin=FLOG, stdout=FLOG, stderr=FLOG)
12
+    subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowblademedialinker", filename], stdin=FLOG, stdout=FLOG, stderr=FLOG)
13
 
14
 
15
 # -------------------------------------------------------- render thread
16
@@ -184,13 +185,15 @@
17
             
18
             dialog.destroy()
19
             
20
-            global load_thread
21
-            load_thread = ProjectLoadThread(filenames[0])
22
-            load_thread.start()
23
-
24
+            self.load_project(filenames[0])
25
         else:
26
             dialog.destroy()
27
 
28
+    def load_project(self, filename):
29
+        global load_thread
30
+        load_thread = ProjectLoadThread(filename)
31
+        load_thread.start()
32
+            
33
     def display_list_changed(self, display_combo):
34
         self.relink_list.fill_data_model()
35
         if display_combo.get_active() == 0:
36
@@ -494,7 +497,18 @@
37
 
38
         target_project.last_save_path = filenames[0]
39
         target_project.name = os.path.basename(filenames[0])
40
-        
41
+    
42
+        # Test that saving is not IOError
43
+        try:
44
+            filehandle = open( target_project.last_save_path, 'w' )
45
+            filehandle.close()
46
+        except IOError as ioe:
47
+            primary_txt = "I/O error({0})".format(ioe.errno)
48
+            secondary_txt = ioe.strerror + "."
49
+            dialogutils.warning_message(primary_txt, secondary_txt, linker_window, is_info=False)
50
+            return 
51
+
52
+        # Relink and save
53
         _relink_project_media_paths()
54
             
55
         persistance.save_project(target_project, target_project.last_save_path)
56
@@ -542,7 +556,7 @@
57
 
58
 
59
 # ----------------------------------------------------------- main
60
-def main(root_path, force_launch=False):
61
+def main(root_path, filename):
62
     gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version())
63
     print "GTK+ version:", gtk_version
64
     editorstate.gtk_version = gtk_version
65
@@ -566,6 +580,10 @@
66
     Gdk.threads_init()
67
     Gdk.threads_enter()
68
 
69
+    # Request dark them if so desired
70
+    if editorpersistance.prefs.dark_theme == True:
71
+        Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", True)
72
+
73
     repo = mlt.Factory().init()
74
 
75
     # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs 
76
@@ -587,6 +605,9 @@
77
     global linker_window
78
     linker_window = MediaLinkerWindow()
79
 
80
+    if filename != NO_PROJECT_AT_LAUNCH:
81
+        linker_window.load_project(filename)
82
+
83
     Gtk.main()
84
     Gdk.threads_leave()
85
     
86
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/medialog.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/medialog.py Changed
141
 
1
@@ -37,6 +37,7 @@
2
 import editorstate
3
 from editorstate import PROJECT
4
 import monitorevent
5
+import render
6
 import respaths
7
 import updater
8
 import utils
9
@@ -48,6 +49,14 @@
10
 
11
 actions_popup_menu = Gtk.Menu()        
12
 
13
+# Sort order
14
+TIME_SORT = appconsts.TIME_SORT
15
+NAME_SORT = appconsts.NAME_SORT
16
+COMMENT_SORT = appconsts.COMMENT_SORT
17
+
18
+sorting_order = TIME_SORT
19
+
20
+                
21
 class MediaLogEvent:
22
     def __init__(self, event_type, mark_in, mark_out, name, path):
23
         self.event_type = event_type
24
@@ -87,7 +96,7 @@
25
                                         clip.name,
26
                                         clip.path)
27
             editorstate.PROJECT().media_log.append(log_event)
28
-    _update_list_view()
29
+    _update_list_view(log_event)
30
     
31
 
32
 # ----------------------------------------------------------- gui events
33
@@ -129,13 +138,15 @@
34
                                 media_file.path)
35
     editorstate.PROJECT().media_log.append(log_event)
36
     editorstate.PROJECT().add_to_group(_get_current_group_index(), [log_event])
37
-    _update_list_view()
38
+    _update_list_view(log_event)
39
 
40
-def _update_list_view():
41
+def _update_list_view(log_event):
42
     widgets.media_log_view.fill_data_model()
43
     max_val = widgets.media_log_view.treeview.get_vadjustment().get_upper()
44
     gui.middle_notebook.set_current_page(1)
45
-    widgets.media_log_view.treeview.get_selection().select_path(str(len(get_current_filtered_events())-1))
46
+    view_group = get_current_filtered_events()
47
+    event_index = view_group.index(log_event)
48
+    widgets.media_log_view.treeview.get_selection().select_path(str(event_index))
49
     widgets.media_log_view.treeview.get_vadjustment().set_value(max_val)
50
 
51
 def log_item_name_edited(cell, path, new_text, user_data):
52
@@ -201,11 +212,22 @@
53
         widgets.media_log_view.fill_data_model()
54
     elif item_id == "display":
55
         display_item(row)
56
+    elif item_id == "renderslowmo":
57
+        render_slowmo_from_item(row)
58
+
59
+def render_slowmo_from_item(row):
60
+    log_events = get_current_filtered_events()
61
+    event_item = log_events[row]
62
+    media_file = PROJECT().get_media_file_for_path(event_item.path)
63
+    media_file.mark_in = event_item.mark_in
64
+    media_file.mark_out = event_item.mark_out
65
+    render.render_frame_buffer_clip(media_file, True)
66
 
67
-def get_current_filtered_events():
68
+def get_current_filtered_events():   
69
     log_events = PROJECT().get_filtered_media_log_events(widgets.group_view_select.get_active() - 1,
70
                                                          widgets.star_check.get_active(),
71
-                                                         widgets.star_not_active_check.get_active())
72
+                                                         widgets.star_not_active_check.get_active(),
73
+                                                         sorting_order)
74
     return log_events
75
 
76
 def _get_current_group_index():
77
@@ -309,6 +331,46 @@
78
     _unsensitive_for_all_view(item)
79
     actions_menu.add(item)
80
 
81
+    guiutils.add_separetor(actions_menu)
82
+    
83
+    sort_item = Gtk.MenuItem(_("Sort by").encode('utf-8'))
84
+    sort_menu = Gtk.Menu()
85
+    time_item = Gtk.RadioMenuItem()
86
+    time_item.set_label(_("Time").encode('utf-8'))
87
+    time_item.set_active(True)
88
+    time_item.show()
89
+    time_item.connect("activate", lambda w: _sorting_changed("time"))
90
+    sort_menu.append(time_item)
91
+
92
+    name_item = Gtk.RadioMenuItem.new_with_label([time_item], _("File Name").encode('utf-8'))
93
+    name_item.connect("activate", lambda w: _sorting_changed("name"))
94
+    name_item.show()
95
+    sort_menu.append(name_item)
96
+
97
+    comment_item = Gtk.RadioMenuItem.new_with_label([time_item], _("Comment").encode('utf-8'))
98
+    comment_item.connect("activate", lambda w: _sorting_changed("comment"))
99
+    comment_item.show()
100
+    sort_menu.append(comment_item)
101
+
102
+    global sorting_order
103
+    if sorting_order == TIME_SORT:
104
+        time_item.set_active(True)
105
+    elif sorting_order == NAME_SORT:
106
+        name_item.set_active(True)
107
+    else:# "comment"
108
+        comment_item.set_active(True)
109
+        
110
+    """
111
+    if editorpersistance.prefs.midbar_tc_left == True:
112
+        tc_left.set_active(True)
113
+    else:
114
+        tc_middle.set_active(True)
115
+    """
116
+
117
+    sort_item.set_submenu(sort_menu)
118
+    sort_item.show()
119
+    actions_menu.add(sort_item)
120
+        
121
     actions_menu.popup(None, None, None, None, event.button, event.time)
122
 
123
 def _unsensitive_for_all_view(item):
124
@@ -420,6 +482,16 @@
125
     widgets.group_view_select.set_active(len(PROJECT().media_log_groups))
126
     update_media_log_view()
127
 
128
+def _sorting_changed(msg):
129
+    global sorting_order
130
+    if msg == "time":
131
+        sorting_order = TIME_SORT
132
+    elif msg == "name":
133
+        sorting_order = NAME_SORT
134
+    else:# "comment"
135
+        sorting_order = COMMENT_SORT
136
+
137
+    media_log_filtering_changed()
138
     
139
 # ------------------------------------------------------------ gui
140
 def get_media_log_list_view():
141
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/menuactions.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/menuactions.py Changed
148
 
1
@@ -58,7 +58,6 @@
2
         threading.Thread.__init__(self)
3
 
4
     def run(self):
5
-        # NEEDS FIXING FOR COMPACT PROJECTS
6
         Gdk.threads_enter()
7
         recreate_progress_window = dialogs.recreate_icons_progress_dialog()
8
         time.sleep(0.1)
9
@@ -74,13 +73,14 @@
10
 
11
             if ((not isinstance(media_file, patternproducer.AbstractBinClip))
12
                 and (not isinstance(media_file, projectdata.BinColorClip))):
13
-                if media_file.icon_path == no_icon_path:
14
-                    if media_file.type == appconsts.AUDIO:
15
-                        icon_path = respaths.IMAGE_PATH + "audio_file.png"
16
-                    else:
17
-                        (icon_path, length) = projectdata.thumbnailer.write_image(media_file.path)
18
-                    media_file.icon_path = icon_path
19
-                    media_file.create_icon()
20
+                if media_file.type == appconsts.AUDIO:
21
+                    icon_path = respaths.IMAGE_PATH + "audio_file.png"
22
+                    media_file.info = None
23
+                else:
24
+                    (icon_path, length, info) = projectdata.thumbnailer.write_image(media_file.path)
25
+                    media_file.info = info
26
+                media_file.icon_path = icon_path
27
+                media_file.create_icon()
28
 
29
             loaded = loaded + 1
30
             
31
@@ -117,114 +117,9 @@
32
     dialogs.about_dialog(gui.editor_window)
33
 
34
 def environment():
35
-    dialogs.environment_dialog(gui.editor_window, write_env_data)
36
+    dialogs.environment_dialog(gui.editor_window)
37
 
38
-# ----------------------------------------------------- environment data
39
-def write_env_data():
40
-    dialogs.save_env_data_dialog(write_out_env_data_cb)
41
-
42
-def write_out_env_data_cb(dialog, response_id):
43
-    if response_id == Gtk.ResponseType.ACCEPT:
44
-        filenames = dialog.get_filenames()
45
-        file_path = filenames[0]
46
-        # Build env data string list
47
-        str_list = []
48
-        str_list.append("FLOWBLADE RUNTIME ENVIROMNMENT\n")
49
-        str_list.append("------------------------------\n")
50
-        str_list.append("\n")
51
-        str_list.append("APPLICATION AND LIBRARIES\n")
52
-        str_list.append("-------------------------\n")
53
-        str_list.append("Application version: " + editorstate.appversion + "\n")
54
-        if editorstate.app_running_from == editorstate.RUNNING_FROM_INSTALLATION:
55
-            run_type = "INSTALLATION"
56
-        else:
57
-            run_type = "DEVELOPER VERSION"
58
-        str_list.append("Application running from: " + run_type + "\n")
59
-        str_list.append("MLT version: " + str(editorstate.mlt_version) + "\n")
60
-        try:
61
-            major, minor, rev = editorstate.gtk_version
62
-            gtk_ver = str(major) + "." + str(minor) + "." + str(rev)
63
-        except:
64
-            gtk_ver = str(editorstate.gtk_version)
65
-        str_list.append("GTK VERSION: " + gtk_ver + "\n")
66
-        str_list.append("SCREEN_HEIGHT: " +  str(editorstate.SCREEN_HEIGHT) + "\n")
67
-
68
-        str_list.append("\n")
69
-        str_list.append("PLATFORM\n")
70
-        str_list.append("--------\n")
71
-        str_list.append(platform.platform())
72
-
73
-        str_list.append("\n")
74
-        str_list.append("\n")
75
-        str_list.append("FORMATS\n")
76
-        str_list.append("-------\n")
77
-        sorted_formats = sorted(mltenv.formats)
78
-        for f in sorted_formats:
79
-            str_list.append(f + "\n")
80
-        str_list.append("\n")
81
-        str_list.append("\n")
82
-        str_list.append("VIDEO_CODECS\n")
83
-        str_list.append("------------\n")
84
-        sorted_vcodecs = sorted(mltenv.vcodecs)
85
-        for vc in sorted_vcodecs:
86
-            str_list.append(vc + "\n")
87
-        str_list.append("\n")
88
-        str_list.append("\n")
89
-        str_list.append("AUDIO_CODECS\n")
90
-        str_list.append("------------\n")
91
-        sorted_acodecs = sorted(mltenv.acodecs)
92
-        for ac in sorted_acodecs:
93
-            str_list.append(ac + "\n")
94
-        str_list.append("\n")
95
-        str_list.append("\n")
96
-        str_list.append("MLT SERVICES\n")
97
-        str_list.append("------------\n")
98
-        sorted_services = sorted(mltenv.services)
99
-        for s in sorted_services:
100
-            str_list.append(s + "\n")
101
-        str_list.append("\n")
102
-        str_list.append("\n")
103
-        str_list.append("MLT TRANSITIONS\n")
104
-        str_list.append("---------------\n")
105
-        sorted_transitions = sorted(mltenv.transitions)
106
-        for t in sorted_transitions:
107
-            str_list.append(t + "\n")
108
-        str_list.append("\n")
109
-        str_list.append("\n")
110
-        str_list.append("ENCODING OPTIONS\n")
111
-        str_list.append("----------------\n")
112
-        enc_ops = renderconsumer.encoding_options + renderconsumer.not_supported_encoding_options
113
-        for e_opt in enc_ops:
114
-            if e_opt.supported:
115
-                msg = e_opt.name + " AVAILABLE\n"
116
-            else:
117
-                msg = e_opt.name + " NOT AVAILABLE, " + e_opt.err_msg + " MISSING\n"
118
-            str_list.append(msg)
119
-        str_list.append("\n")
120
-        str_list.append("\n")
121
-        str_list.append("MISSING FILTERS\n")
122
-        str_list.append("---------------\n")
123
-        for f in mltfilters.not_found_filters:
124
-            msg = "mlt.Filter " + f.mlt_service_id + " FOR FILTER " + f.name + " NOT FOUND\n"
125
-            str_list.append(msg)
126
-        str_list.append("\n")
127
-        str_list.append("\n")
128
-        str_list.append("MISSING TRANSITIONS\n")
129
-        str_list.append("---------------\n")
130
-        for t in mlttransitions.not_found_transitions:
131
-            msg = "mlt.Transition " + t.mlt_service_id + " FOR TRANSITION " + t.name + " NOT FOUND\n"
132
-            str_list.append(msg)
133
-
134
-        # Write out data
135
-        env_text = ''.join(str_list)
136
-        env_file = open(file_path, "w")
137
-        env_file.write(env_text)
138
-        env_file.close()
139
-
140
-        dialog.destroy()
141
-    else:
142
-        dialog.destroy()
143
-        
144
+# ----------------------------------------------------- environment data        
145
 def quick_reference():
146
     try:
147
         url = "file://" + respaths.HELP_DOC
148
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/middlebar.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/middlebar.py Changed
102
 
1
@@ -23,10 +23,12 @@
2
 from gi.repository import Gtk
3
 
4
 import audiomonitoring
5
+import batchrendering
6
 import editevent
7
 import editorpersistance
8
 import editorstate
9
 import glassbuttons
10
+import gmic
11
 import gui
12
 import guicomponents
13
 import guiutils
14
@@ -108,11 +110,17 @@
15
     editor_window.zoom_buttons.widget.set_tooltip_text(_("Zoom In - Mouse Middle Scroll\n Zoom Out - Mouse Middle Scroll\n Zoom Length - Mouse Middle Click"))
16
 
17
     editor_window.edit_buttons = glassbuttons.GlassButtonsGroup(46, 23, 2, 4, 5)
18
+    editor_window.edit_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "dissolve.png"), tlineaction.add_transition_pressed)
19
     editor_window.edit_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "cut.png"), tlineaction.cut_pressed)
20
-    editor_window.edit_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "splice_out.png"), tlineaction.splice_out_button_pressed)
21
-    editor_window.edit_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "lift.png"), tlineaction.lift_button_pressed)
22
-    editor_window.edit_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "resync.png"), tlineaction.resync_button_pressed)
23
-    editor_window.edit_buttons.widget.set_tooltip_text(_("Cut - X\nSplice Out - Delete\nLift\nResync Selected"))
24
+    editor_window.edit_buttons.widget.set_tooltip_text(_("Add Rendered Transition - 2 clips selected\nAdd Rendered Fade - 1 clip selected\nCut - X"))
25
+
26
+    editor_window.edit_buttons_2 = glassbuttons.GlassButtonsGroup(46, 23, 2, 4, 5)
27
+    editor_window.edit_buttons_2.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "splice_out.png"), tlineaction.splice_out_button_pressed)
28
+    editor_window.edit_buttons_2.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "lift.png"), tlineaction.lift_button_pressed)
29
+    #editor_window.edit_buttons_2.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "delete_range.png"), tlineaction.append_button_pressed)
30
+    editor_window.edit_buttons_2.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "resync.png"), tlineaction.resync_button_pressed)
31
+    editor_window.edit_buttons_2.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "split_audio.png"), tlineaction.split_audio_button_pressed)
32
+    editor_window.edit_buttons_2.widget.set_tooltip_text(_("Splice Out - Delete\nLift\nResync Selected\nSplit Audio"))
33
 
34
     editor_window.monitor_insert_buttons = glassbuttons.GlassButtonsGroup(46, 23, 2, 4, 5)
35
     editor_window.monitor_insert_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "overwrite_range.png"), tlineaction.range_overwrite_pressed)
36
@@ -121,23 +129,21 @@
37
     editor_window.monitor_insert_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "append_clip.png"), tlineaction.append_button_pressed)
38
     editor_window.monitor_insert_buttons.widget.set_tooltip_text(_("Overwrite Range\nOverwrite Clip - T\nInsert Clip - Y\nAppend Clip - U"))
39
 
40
-    editor_window.undo_redo = glassbuttons.GlassButtonsGroup(46, 23, 2, 2, 7)
41
+    editor_window.undo_redo = glassbuttons.GlassButtonsGroup(28, 23, 2, 2, 7)
42
     editor_window.undo_redo.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "undo.png"), undo.do_undo_and_repaint)
43
     editor_window.undo_redo.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "redo.png"), undo.do_redo_and_repaint)
44
-    editor_window.undo_redo.widget.set_tooltip_text(_("Undo - Ctrl + X\nRedo - Ctrl + Y"))
45
+    editor_window.undo_redo.widget.set_tooltip_text(_("Undo - Ctrl + Z\nRedo - Ctrl + Y"))
46
 
47
     editor_window.tools_buttons = glassbuttons.GlassButtonsGroup(46, 23, 2, 14, 7)
48
     editor_window.tools_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "open_mixer.png"), audiomonitoring.show_audio_monitor)
49
     editor_window.tools_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "open_titler.png"), titler.show_titler)
50
-    editor_window.tools_buttons.widget.set_tooltip_text(_("Audio Mixer\nTitler"))
51
+    editor_window.tools_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "open_gmic.png"), gmic.launch_gmic)
52
+    editor_window.tools_buttons.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "open_renderqueue.png"), lambda :batchrendering.launch_batch_rendering())
53
+    editor_window.tools_buttons.widget.set_tooltip_text(_("Audio Mixer\nTitler\nG'Mic Effects\nBatch Render Queue"))
54
     if editorstate.audio_monitoring_available == False:
55
         editor_window.tools_buttons.sensitive[0] = False
56
         editor_window.tools_buttons.widget.set_tooltip_text(_("Audio Mixer(not available)\nTitler"))
57
 
58
-    editor_window.transition_button = glassbuttons.GlassButtonsGroup(46, 23, 2, 4, 5)
59
-    editor_window.transition_button.add_button(cairo.ImageSurface.create_from_png(IMG_PATH + "dissolve.png"), tlineaction.add_transition_pressed)
60
-    editor_window.transition_button.widget.set_tooltip_text(_("Add Rendered Transition - 2 clips selected\nAdd Rendered Fade - 1 clip selected"))
61
-
62
 def fill_with_TC_LEFT_pattern(buttons_row, window):
63
     global w
64
     w = window
65
@@ -154,7 +160,7 @@
66
     buttons_row.pack_start(Gtk.Label(), True, True, 0)
67
     buttons_row.pack_start(_get_edit_buttons_panel(),False, True, 0)
68
     buttons_row.pack_start(Gtk.Label(), True, True, 0)
69
-    buttons_row.pack_start(_get_transition_button(), False, True, 0)
70
+    buttons_row.pack_start(_get_edit_buttons_2_panel(),False, True, 0)
71
     buttons_row.pack_start(Gtk.Label(), True, True, 0)
72
     buttons_row.pack_start(_get_monitor_insert_buttons(), False, True, 0)
73
 
74
@@ -182,6 +188,8 @@
75
     right_panel.pack_start(Gtk.Label(), True, True, 0)
76
     right_panel.pack_start(_get_edit_buttons_panel(), False, True, 0)
77
     right_panel.pack_start(guiutils.get_pad_label(10, 10), False, True, 0)
78
+    right_panel.pack_start(_get_edit_buttons_2_panel(),False, True, 0)
79
+    right_panel.pack_start(guiutils.get_pad_label(10, 10), False, True, 0)
80
     right_panel.pack_start(_get_monitor_insert_buttons(), False, True, 0)
81
 
82
     buttons_row.pack_start(left_panel, True, True, 0)
83
@@ -197,15 +205,15 @@
84
 def _get_edit_buttons_panel():
85
     return w.edit_buttons.widget
86
 
87
+def _get_edit_buttons_2_panel():
88
+    return w.edit_buttons_2.widget
89
+    
90
 def _get_monitor_insert_buttons():
91
     return w.monitor_insert_buttons.widget
92
 
93
 def _get_tools_buttons():
94
     return w.tools_buttons.widget
95
 
96
-def _get_transition_button():
97
-    return w.transition_button.widget
98
-
99
 def _b(button, icon, remove_relief=False):
100
     button.set_image(icon)
101
     button.set_property("can-focus",  False)
102
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/mltfilters.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/mltfilters.py Changed
9
 
1
@@ -427,6 +427,7 @@
2
     """
3
     clone = FilterObject(filter_object.info)
4
     clone.properties = copy.deepcopy(filter_object.properties)
5
+    clone.non_mlt_properties = copy.deepcopy(filter_object.non_mlt_properties)
6
     clone.create_mlt_filter(mlt_profile)
7
     return clone
8
 
9
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/mltplayer.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/mltplayer.py Changed
28
 
1
@@ -32,7 +32,7 @@
2
 import time
3
 
4
 import gui
5
-import editorpersistance
6
+#import editorpersistance
7
 from editorstate import timeline_visible
8
 import editorstate
9
 import utils
10
@@ -366,6 +366,7 @@
11
         self.render_callbacks.maybe_open_rendered_file_in_bin()
12
         Gdk.threads_leave()
13
 
14
+    """
15
     def jack_output_on(self):
16
         # We're assuming that we are not rendering and consumer is SDL consumer
17
         self.producer.set_speed(0)
18
@@ -398,7 +399,8 @@
19
         self.consumer.start()
20
         
21
         self.jack_output_filter = None
22
-        
23
+    """
24
+
25
     def shutdown(self):
26
         self.ticker.stop_ticker()
27
         self.producer.set_speed(0)
28
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/mltprofiles.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/mltprofiles.py Changed
57
 
1
@@ -119,7 +119,7 @@
2
     """
3
     def_profile_index = get_index_for_name(editorpersistance.prefs.default_profile_name)
4
     if def_profile_index == -1:
5
-        print "default profile from prefs nor found"
6
+        print "default profile from prefs not found"
7
         def_profile_index = get_index_for_name(DEFAULT_DEFAULT_PROFILE)
8
         def_profile_name =  DEFAULT_DEFAULT_PROFILE
9
         if def_profile_index == -1:
10
@@ -138,6 +138,46 @@
11
             return i
12
     return -1
13
 
14
+def get_closest_matching_profile_index(producer_info):
15
+    # producer_info is dict from utils.get_file_producer_info
16
+    width = producer_info["width"]
17
+    height= producer_info["height"]
18
+    fps_num =  producer_info["fps_num"]
19
+    fps_den = producer_info["fps_den"]
20
+    progressive = producer_info["progressive"]
21
+    fps = round(float(float(fps_num)/float(fps_den)), 1)
22
+    
23
+    # We calculate match score for all available profiles and return 
24
+    # the one with the highest score
25
+    current_match_index = -1
26
+    current_match_score = 0
27
+    for i in range(0, len(_profile_list)):
28
+        match_score = 0
29
+        name, profile = _profile_list[i]
30
+
31
+        prof_width = profile.width()
32
+        prof_height = profile.height()
33
+        prof_fps_num =  profile.frame_rate_num()
34
+        prof_fps_den = profile.frame_rate_den()
35
+        prof_progressive = profile.progressive()
36
+        prof_fps = round(float(float(prof_fps_num)/float(prof_fps_den)), 1)
37
+
38
+        if width == prof_width and height == prof_height:
39
+            match_score = match_score + 1000
40
+        if fps == prof_fps:
41
+            match_score = match_score + 100
42
+        if prof_progressive: # prefer progressive always
43
+            match_score = match_score + 10
44
+
45
+        if match_score > current_match_score:
46
+            current_match_score = match_score
47
+            current_match_index = i
48
+
49
+    if current_match_index == -1:
50
+        return get_default_profile_index()
51
+
52
+    return current_match_index
53
+
54
 def _sort_profiles(a, b):
55
     a_desc, a_profile = a
56
     b_desc, b_profile = b
57
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/monitorevent.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/monitorevent.py Changed
30
 
1
@@ -81,23 +81,26 @@
2
 def next_pressed():
3
     if current_is_move_mode():
4
         movemodes.next_pressed()
5
+    """ This is highly fucking suspect, it does an edit immediately
6
+    commented out at 6-1-16  and lets see if anyone complains
7
     elif EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
8
         trimmodes.oneroll_next_pressed()
9
     elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
10
         trimmodes.tworoll_next_pressed()
11
     elif EDIT_MODE() == editorstate.SLIDE_TRIM:
12
         trimmodes.slide_next_pressed()
13
-
14
+    """
15
 def prev_pressed():
16
     if current_is_move_mode():
17
         movemodes.prev_pressed()
18
+    """
19
     elif EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
20
         trimmodes.oneroll_prev_pressed()
21
     elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
22
         trimmodes.tworoll_prev_pressed()
23
     elif EDIT_MODE() == editorstate.SLIDE_TRIM:
24
         trimmodes.slide_prev_pressed()
25
-
26
+    """
27
 def j_pressed():
28
     if timeline_visible():
29
         trimmodes.set_no_edit_trim_mode()
30
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/movemodes.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/movemodes.py Changed
54
 
1
@@ -28,6 +28,7 @@
2
 
3
 import appconsts
4
 import dialogutils
5
+import editorpersistance # Jul-2016 - SvdB - For play/pause button
6
 import dnd
7
 import edit
8
 from editorstate import current_sequence
9
@@ -66,7 +67,15 @@
10
 # These four buttons act differently in trimmodes and move modes
11
 def play_pressed():
12
     # This handles only move modes, see trimmodes.py module for others.
13
-    PLAYER().start_playback()  
14
+    # Jul-2016 - SvdB - Added code to handle play/pause button
15
+    if editorpersistance.prefs.play_pause == True:
16
+        if PLAYER().is_playing():
17
+            PLAYER().stop_playback()
18
+        else:
19
+            PLAYER().start_playback()
20
+    else:
21
+        # Original code
22
+        PLAYER().start_playback()  
23
 
24
 def stop_pressed():
25
     # This handles only move modes, see trimmodes.py module for others.
26
@@ -413,6 +422,7 @@
27
         return
28
         
29
     # Check locking for pressed track
30
+    # This ain't used crrently!!!!!
31
     if _track_is_locked(track):
32
         clear_selected_clips()
33
         pressed_on_selected = False
34
@@ -432,6 +442,7 @@
35
             # seems to a single blank area. All of these must be
36
             # selected together automatically or user will be exposed to
37
             # this impl. detail unnecesserarely.
38
+            # THIS HAS BEEN CHANGED BECAUSE BLANKS ARE NOW AUTO CONSOLIDATED AFTER ALL EDITS.
39
             range_in, range_out = _get_blanck_range(track, clip_index)
40
             _select_multiple_clips(track.id, range_in, range_out)
41
             pressed_on_selected = False
42
@@ -494,9 +505,9 @@
43
                  "track_object":track,
44
                  "to_track_object":track,
45
                  "move_on":False,
46
-                 "press_frame":frame,
47
+                 "press_frame":frame, # on timeline at mouse press
48
                  "current_frame":frame,
49
-                 "first_clip_start":insert_frame,
50
+                 "first_clip_start":insert_frame,  # on timeline at mouse press
51
                  "insert_frame":insert_frame,
52
                  "clip_lengths":clip_lengths,
53
                  "mouse_start_x":x,
54
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/panels.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/panels.py Changed
92
 
1
@@ -236,7 +236,7 @@
2
     return align
3
 
4
 def get_file_properties_panel(data):
5
-    media_file, img, size, length, vcodec, acodec, channels, frequency, fps = data
6
+    media_file, img, size, length, vcodec, acodec, channels, frequency, fps, match_profile_name, matches_current_profile = data
7
     
8
     row0 = get_two_column_box(get_bold_label(_("Name:")), Gtk.Label(label=media_file.name))
9
     row00 = get_two_column_box(get_bold_label(_("Path:")), Gtk.Label(label=media_file.path))
10
@@ -247,6 +247,8 @@
11
     row3 = get_two_column_box(get_bold_label(_("Audio Codec:")), Gtk.Label(label=acodec))
12
     row4 = get_two_column_box(get_bold_label(_("Audio Channels:")), Gtk.Label(label=channels))
13
     row5 = get_two_column_box(get_bold_label(_("Audio Sample Rate:")), Gtk.Label(label=frequency))
14
+    row6 = get_two_column_box(get_bold_label(_("Best Profile:")), Gtk.Label(label=match_profile_name))
15
+    row7 = get_two_column_box(get_bold_label(_("Matches Project Profile:")), Gtk.Label(label=matches_current_profile))
16
     
17
     vbox = Gtk.VBox(False, 2)
18
     vbox.pack_start(img, False, False, 0)
19
@@ -260,13 +262,17 @@
20
     vbox.pack_start(row3, False, False, 0)
21
     vbox.pack_start(row4, False, False, 0)
22
     vbox.pack_start(row5, False, False, 0)
23
+    vbox.pack_start(row6, False, False, 0)
24
+    vbox.pack_start(row7, False, False, 0)
25
     vbox.pack_start(Gtk.Label(), True, True, 0)
26
     
27
     return vbox
28
     
29
 def get_clip_properties_panel(data):
30
-    length, size, path, vcodec, acodec = data
31
-    
32
+    mark_in, mark_out, length, size, path, vcodec, acodec = data
33
+
34
+    row0 = get_two_column_box(get_bold_label(_("Mark In:")), Gtk.Label(label=mark_in))
35
+    row00 = get_two_column_box(get_bold_label(_("Mark Out:")), Gtk.Label(label=mark_out))
36
     row1 = get_two_column_box(get_bold_label(_("Clip Length:")), Gtk.Label(label=length))
37
     row2 = get_two_column_box(get_bold_label(_("Image Size:")), Gtk.Label(label=size))
38
     row3 = get_two_column_box(get_bold_label(_("Media Path:")), Gtk.Label(label=path))
39
@@ -274,6 +280,8 @@
40
     row5 = get_two_column_box(get_bold_label(_("Audio Codec:")), Gtk.Label(label=acodec))
41
     
42
     vbox = Gtk.VBox(False, 2)
43
+    vbox.pack_start(row0, False, False, 0)
44
+    vbox.pack_start(row00, False, False, 0)
45
     vbox.pack_start(row1, False, False, 0)
46
     vbox.pack_start(row2, False, False, 0)
47
     vbox.pack_start(row3, False, False, 0)
48
@@ -346,21 +354,16 @@
49
     filler = Gtk.Label()
50
     filler.set_size_request(10,10)
51
 
52
-    out_clip_label = Gtk.Label(label=_("From Clip Handle:"))
53
-    out_clip_value = Gtk.Label(label=trans_data["from_handle"])
54
+    out_clip_label = Gtk.Label(label=_("First Clip Out Handle:"))
55
+    out_clip_value = Gtk.Label(label=str(trans_data["from_handle"]) + _(" frame(s)"))
56
     
57
-    in_clip_label = Gtk.Label(label=_("To Clip Handle:"))
58
-    in_clip_value = Gtk.Label(label=trans_data["to_handle"])
59
+    in_clip_label = Gtk.Label(label=_("Second Clip In Handle:"))
60
+    in_clip_value = Gtk.Label(label=str(trans_data["to_handle"]) + _(" frame(s)"))
61
     
62
-    max_label = Gtk.Label(label=_("Max. Transition Length:"))
63
-    max_value = Gtk.Label(label=trans_data["max_length"])
64
-
65
     out_handle_row = get_two_column_box(out_clip_label, 
66
                                         out_clip_value)
67
     in_handle_row = get_two_column_box(in_clip_label, 
68
                                        in_clip_value)
69
-    max_row = get_two_column_box(max_label, 
70
-                                 max_value)
71
 
72
     # Encoding widgets
73
     encodings_cb = Gtk.ComboBoxText()
74
@@ -385,7 +388,6 @@
75
     data_vbox = Gtk.VBox(False, 2)
76
     data_vbox.pack_start(out_handle_row, False, False, 0)
77
     data_vbox.pack_start(in_handle_row, False, False, 0)
78
-    data_vbox.pack_start(max_row, False, False, 0)
79
     
80
     enconding_vbox = Gtk.VBox(False, 2)
81
     enconding_vbox.pack_start(encodings_cb, False, False, 0)
82
@@ -393,8 +395,8 @@
83
     
84
     vbox = Gtk.VBox(False, 2)
85
     vbox.pack_start(get_named_frame(_("Transition Options"),  edit_vbox), True, True, 0)
86
-    vbox.pack_start(get_named_frame(_("Clips info"),  data_vbox), True, True, 0)
87
     vbox.pack_start(get_named_frame(_("Encoding"),  enconding_vbox), True, True, 0)
88
+    vbox.pack_start(get_named_frame(_("Media Overlap info"),  data_vbox), True, True, 0)
89
 
90
     alignment = guiutils.set_margins(vbox, 12, 24, 12, 12)
91
 
92
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/patternproducer.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/patternproducer.py Changed
11
 
1
@@ -193,6 +193,9 @@
2
         
3
         self.create_icon()
4
 
5
+    def matches_project_profile(self):
6
+        return True # these are created to match project profile
7
+
8
     def create_mlt_producer(self, profile):
9
         print "create_mlt_producer not implemented"
10
 
11
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/persistance.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/persistance.py Changed
103
 
1
@@ -81,7 +81,9 @@
2
 # 'snapshot_paths != None' flags that snapsave is being done and paths need to be replaced 
3
 snapshot_paths = None
4
 
5
-
6
+# Used to compute in/out points when saving to change profile
7
+_fps_conv_mult = 1.0
8
+    
9
 class FileProducerNotFoundError(Exception):
10
     """
11
     We're only catching this, other errors we'll just crash on load
12
@@ -109,7 +111,7 @@
13
         Gdk.threads_leave()
14
 
15
 # -------------------------------------------------- SAVE
16
-def save_project(project, file_path):
17
+def save_project(project, file_path, changed_profile_desc=None):
18
     """
19
     Creates pickleable project object
20
     """
21
@@ -118,6 +120,15 @@
22
     # Get shallow copy
23
     s_proj = copy.copy(project)
24
     
25
+    # Implements "change profile" functionality
26
+    global _fps_conv_mult
27
+    _fps_conv_mult = 1.0
28
+    if changed_profile_desc != None:
29
+        _fps_conv_mult = mltprofiles.get_profile(changed_profile_desc).fps() / mltprofiles.get_profile(s_proj.profile_desc).fps()
30
+        s_proj.profile_desc = changed_profile_desc
31
+        print "Saving changed profile project: ", changed_profile_desc
32
+        print "FPS conversion multiplier:", _fps_conv_mult
33
+
34
     # Set current sequence index
35
     s_proj.c_seq_index = project.sequences.index(project.c_seq)
36
     
37
@@ -239,7 +250,10 @@
38
     # Get replace sync data
39
     if s_clip.sync_data != None:
40
          s_clip.sync_data = get_p_sync_data(s_clip.sync_data)
41
-    
42
+
43
+    if _fps_conv_mult != 1.0:
44
+        _update_clip_in_out_for_fps_change(s_clip)
45
+
46
     # Remove unpicleable attributes
47
     remove_attrs(s_clip, CLIP_REMOVE)
48
 
49
@@ -268,7 +282,7 @@
50
 
51
 def get_p_filter(f):
52
     """
53
-    Creates pickleable version MLT Filter object.
54
+    Creates pickleable version of MLT Filter object.
55
     """
56
     s_filter = copy.copy(f)
57
     remove_attrs(s_filter, FILTER_REMOVE)
58
@@ -285,6 +299,8 @@
59
         s_compositor = copy.copy(compositor)
60
         s_compositor.transition = copy.copy(compositor.transition)
61
         s_compositor.transition.mlt_transition = None
62
+        if _fps_conv_mult != 1.0:
63
+            _update_compositor_in_out_for_fps_change(s_compositor)
64
         s_compositors.append(s_compositor)
65
 
66
     return s_compositors
67
@@ -307,7 +323,14 @@
68
         except Exception:
69
             pass
70
 
71
+def _update_clip_in_out_for_fps_change(s_clip):
72
+    s_clip.clip_in = int(s_clip.clip_in * _fps_conv_mult)
73
+    s_clip.clip_out = int(s_clip.clip_out * _fps_conv_mult)
74
 
75
+def _update_compositor_in_out_for_fps_change(s_compositor):
76
+    s_compositor.clip_in = int(s_compositor.clip_in * _fps_conv_mult)
77
+    s_compositor.clip_out = int(s_compositor.clip_out * _fps_conv_mult)
78
+ 
79
 # -------------------------------------------------- LOAD
80
 def load_project(file_path, icons_and_thumnails=True, relinker_load=False):
81
     _show_msg("Unpickling")
82
@@ -316,8 +339,6 @@
83
     f = open(file_path)
84
     project = pickle.load(f)
85
 
86
-    project.name = project.name.encode("utf-8")
87
-
88
     # Relinker only operates on pickleable python data 
89
     if relinker_load:
90
         FIX_MISSING_PROJECT_ATTRS(project)
91
@@ -375,7 +396,10 @@
92
         # Remove 2018
93
         if (not(hasattr(media_file,  "is_proxy_file"))):
94
             FIX_N_TO_4_MEDIA_FILE_COMPATIBILITY(media_file)
95
-
96
+        # This attr was added for 1.8. It is not computed for older projects.
97
+        if (not hasattr(media_file, "info")):
98
+            media_file.info = None
99
+       
100
     if icons_and_thumnails == True:
101
         _show_msg(_("Loading icons"))
102
         for k, media_file in project.media_files.iteritems():
103
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/positionbar.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/positionbar.py Changed
105
 
1
@@ -33,7 +33,11 @@
2
 import editorstate
3
 import gui
4
 import guiutils
5
-import trimmodes
6
+trimmodes_set_no_edit_trim_mode = None # This monkey patched in app.py to avoid unncessary dependencies in gmic.py
7
+
8
+#import trimmodes
9
+
10
+
11
 
12
 # Draw params
13
 BAR_WIDTH = 200 # NOTE: DOES NOT HAVE ANY EFFECT IF OTHER WIDTHS MAKE MONITOR AREA MIN WIDTH BIGGER, AS THIS EXPANDS TO FILL
14
@@ -65,7 +69,7 @@
15
     GUI component used to set/display position in clip/timeline
16
     """
17
 
18
-    def __init__(self):
19
+    def __init__(self, handle_trimmodes=True):
20
         self.widget = CairoDrawableArea2(   BAR_WIDTH, 
21
                                             BAR_HEIGHT, 
22
                                             self._draw)
23
@@ -78,6 +82,8 @@
24
         self.disabled = False
25
         self.mouse_release_listener = None # when used in tools (Titler ate.) this used to update bg image
26
 
27
+        self.handle_trimmodes = handle_trimmodes
28
+
29
         if editorpersistance.prefs.dark_theme == True:
30
             global LINE_COLOR, DISABLED_BG_COLOR, SELECTED_RANGE_COLOR, MARK_COLOR
31
             LINE_COLOR = DARK_LINE_COLOR
32
@@ -177,17 +183,20 @@
33
         cr.line_to(self._pos + 0.5, BAR_HEIGHT)
34
         cr.stroke()
35
 
36
-        speed = editorstate.PLAYER().producer.get_speed()
37
-        if speed != 1.0 and speed != 0.0:
38
-            cr.set_source_rgb(*SPEED_TEST_COLOR)
39
-            cr.select_font_face ("sans-serif",
40
-                                 cairo.FONT_SLANT_NORMAL,
41
-                                 cairo.FONT_WEIGHT_BOLD)
42
-            cr.set_font_size(11)
43
-            disp_str = str(speed) + "x"
44
-            tx, ty, twidth, theight, dx, dy = cr.text_extents(disp_str)
45
-            cr.move_to( w/2 - twidth/2, 13)
46
-            cr.show_text(disp_str)
47
+        # This only needed when this widget is used in main app, 
48
+        # for gmic.py process self.handle_trimmodes == False.
49
+        if self.handle_trimmodes == True:
50
+            speed = editorstate.PLAYER().producer.get_speed()
51
+            if speed != 1.0 and speed != 0.0:
52
+                cr.set_source_rgb(*SPEED_TEST_COLOR)
53
+                cr.select_font_face ("sans-serif",
54
+                                     cairo.FONT_SLANT_NORMAL,
55
+                                     cairo.FONT_WEIGHT_BOLD)
56
+                cr.set_font_size(11)
57
+                disp_str = str(speed) + "x"
58
+                tx, ty, twidth, theight, dx, dy = cr.text_extents(disp_str)
59
+                cr.move_to( w/2 - twidth/2, 13)
60
+                cr.show_text(disp_str)
61
 
62
     def draw_mark_in(self, cr, h):
63
         """
64
@@ -201,11 +210,11 @@
65
         cr.move_to (x, MARK_PAD)
66
         cr.line_to (x, h - MARK_PAD)
67
         cr.line_to (x - 2 * MARK_LINE_WIDTH, h - MARK_PAD)
68
-        cr.line_to (x - 2 * MARK_LINE_WIDTH, 
69
+        cr.line_to (x - 1 * MARK_LINE_WIDTH, 
70
                     h - MARK_LINE_WIDTH - MARK_PAD) 
71
         cr.line_to (x - MARK_LINE_WIDTH, h - MARK_LINE_WIDTH - MARK_PAD )
72
         cr.line_to (x - MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD)
73
-        cr.line_to (x - 2 * MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD )
74
+        cr.line_to (x - 1 * MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD )
75
         cr.line_to (x - 2 * MARK_LINE_WIDTH, MARK_PAD)
76
         cr.close_path();
77
 
78
@@ -224,11 +233,11 @@
79
         cr.move_to (x, MARK_PAD)
80
         cr.line_to (x, h - MARK_PAD)
81
         cr.line_to (x + 2 * MARK_LINE_WIDTH, h - MARK_PAD)
82
-        cr.line_to (x + 2 * MARK_LINE_WIDTH, 
83
+        cr.line_to (x + 1 * MARK_LINE_WIDTH, 
84
                     h - MARK_LINE_WIDTH - MARK_PAD) 
85
         cr.line_to (x + MARK_LINE_WIDTH, h - MARK_LINE_WIDTH - MARK_PAD )
86
         cr.line_to (x + MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD)
87
-        cr.line_to (x + 2 * MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD )
88
+        cr.line_to (x + 1 * MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD )
89
         cr.line_to (x + 2 * MARK_LINE_WIDTH, MARK_PAD)
90
         cr.close_path();
91
 
92
@@ -241,8 +250,10 @@
93
         """
94
         if self.disabled:
95
             return
96
-        if editorstate.timeline_visible():
97
-            trimmodes.set_no_edit_trim_mode()
98
+
99
+        if self.handle_trimmodes == True:
100
+            if editorstate.timeline_visible():
101
+                trimmodes_set_no_edit_trim_mode()
102
 
103
         if((event.button == 1)
104
             or(event.button == 3)):
105
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/preferenceswindow.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/preferenceswindow.py Changed
122
 
1
@@ -41,7 +41,7 @@
2
                     Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
3
                     (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
4
                     _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
5
-    
6
+
7
     gen_opts_panel, gen_opts_widgets = _general_options_panel(_thumbs_select_clicked, _renders_select_clicked)
8
     edit_prefs_panel, edit_prefs_widgets = _edit_prefs_panel()
9
     view_pres_panel, view_pref_widgets = _view_prefs_panel()
10
@@ -57,6 +57,8 @@
11
     dialog.vbox.pack_start(notebook, True, True, 0)
12
     dialogutils.set_outer_margins(dialog.vbox)
13
     dialogutils.default_behaviour(dialog)
14
+    # Jul-2016 - SvdB - The next line is to get rid of the message "GtkDialog mapped without a transient parent. This is discouraged."
15
+    dialog.set_transient_for(gui.editor_window.window)
16
     dialog.show_all()
17
 
18
 def _thumbs_select_clicked(widget):
19
@@ -76,7 +78,7 @@
20
         return
21
 
22
     dialog.destroy()
23
-    
24
+
25
 def _general_options_panel(folder_select_clicked_cb, render_folder_select_clicked_cb):
26
     prefs = editorpersistance.prefs
27
 
28
@@ -113,9 +115,9 @@
29
     autosave_combo.set_active(prefs.auto_save_delay_value_index)
30
 
31
     load_order_combo  = Gtk.ComboBoxText()
32
-    load_order_combo.append_text("Absolute paths first, relative second")
33
-    load_order_combo.append_text("Relative paths first, absolute second")
34
-    load_order_combo.append_text("Absolute paths only")
35
+    load_order_combo.append_text(_("Absolute paths first, relative second"))
36
+    load_order_combo.append_text(_("Relative paths first, absolute second"))
37
+    load_order_combo.append_text(_("Absolute paths only"))
38
     load_order_combo.set_active(prefs.media_load_order)
39
 
40
     # Layout
41
@@ -178,6 +180,12 @@
42
     cover_delete = Gtk.CheckButton()
43
     cover_delete.set_active(prefs.trans_cover_delete)
44
     
45
+    # Jul-2016 - SvdB - For play_pause button
46
+    play_pause_button = Gtk.CheckButton()
47
+    # The following test is to make sure play_pause can be used for the initial value. If not found, then leave uninitialized
48
+    if hasattr(prefs, 'play_pause'):
49
+        play_pause_button.set_active(prefs.play_pause)    
50
+    
51
     # Layout
52
     row1 = _row(guiutils.get_checkbox_row_box(auto_play_in_clip_monitor, Gtk.Label(label=_("Autoplay new Clips in Clip Monitor"))))
53
     row2 = _row(guiutils.get_checkbox_row_box(auto_center_on_stop, Gtk.Label(label=_("Center Current Frame on Playback Stop"))))
54
@@ -187,6 +195,8 @@
55
     row7 = _row(guiutils.get_checkbox_row_box(remember_clip_frame, Gtk.Label(label=_("Remember Monitor Clip Frame"))))
56
     row8 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Media drag'n'drop action on non-V1 tracks")), overwrite_clip_drop, PREFERENCES_LEFT))
57
     row9 = _row(guiutils.get_checkbox_row_box(cover_delete, Gtk.Label(label=_("Cover Transition/Fade clips on delete if possible"))))
58
+    # Jul-2016 - SvdB - For play_pause button
59
+    row10 = _row(guiutils.get_checkbox_row_box(play_pause_button, Gtk.Label(label=_("Enable single Play/Pause button"))))
60
     
61
     vbox = Gtk.VBox(False, 2)
62
     vbox.pack_start(row5, False, False, 0)
63
@@ -197,12 +207,15 @@
64
     vbox.pack_start(row7, False, False, 0)
65
     vbox.pack_start(row8, False, False, 0)
66
     vbox.pack_start(row9, False, False, 0)
67
+    # Jul-2016 - SvdB - For play_pause button
68
+    vbox.pack_start(row10, False, False, 0)
69
     vbox.pack_start(Gtk.Label(), True, True, 0)
70
-    
71
+
72
     guiutils.set_margins(vbox, 12, 0, 12, 12)
73
 
74
+    # Jul-2016 - SvdB - Added play_pause_button
75
     return vbox, (auto_play_in_clip_monitor, auto_center_on_stop, gfx_length_spin,
76
-                   trim_exit_on_empty, quick_enter_trim, remember_clip_frame, overwrite_clip_drop, cover_delete)
77
+                   trim_exit_on_empty, quick_enter_trim, remember_clip_frame, overwrite_clip_drop, cover_delete, play_pause_button)
78
 
79
 def _view_prefs_panel():
80
     prefs = editorpersistance.prefs
81
@@ -210,7 +223,7 @@
82
     # Widgets
83
     force_english_check = Gtk.CheckButton()
84
     force_english_check.set_active(prefs.use_english_always)
85
-    
86
+
87
     display_splash_check = Gtk.CheckButton()
88
     display_splash_check.set_active(prefs.display_splash_screen)
89
 
90
@@ -231,7 +244,7 @@
91
         dark_combo.set_active(0)
92
 
93
     theme_combo = Gtk.ComboBoxText()
94
-    for theme in gui._THEME_COLORS: 
95
+    for theme in gui._THEME_COLORS:
96
         theme_combo.append_text(theme[4])
97
     theme_combo.set_active(prefs.theme_fallback_colors)
98
 
99
@@ -250,7 +263,7 @@
100
     row3 =  _row(guiutils.get_two_column_box(Gtk.Label(label=_("Icons and color optimized for:")), dark_combo, PREFERENCES_LEFT))
101
     row4 =  _row(guiutils.get_two_column_box(Gtk.Label(label=_("Theme detection fail fallback colors:")), theme_combo, PREFERENCES_LEFT))
102
     row5 =  _row(guiutils.get_two_column_box(Gtk.Label(label=_("Default audio levels display:")), audio_levels_combo, PREFERENCES_LEFT))
103
-    
104
+
105
     vbox = Gtk.VBox(False, 2)
106
     vbox.pack_start(row0, False, False, 0)
107
     vbox.pack_start(row1, False, False, 0)
108
@@ -259,11 +272,11 @@
109
     vbox.pack_start(row4, False, False, 0)
110
     vbox.pack_start(row5, False, False, 0)
111
     vbox.pack_start(Gtk.Label(), True, True, 0)
112
-    
113
+
114
     guiutils.set_margins(vbox, 12, 0, 12, 12)
115
 
116
     return vbox, (force_english_check, display_splash_check, buttons_combo, dark_combo, theme_combo, audio_levels_combo)
117
-    
118
+
119
 def _row(row_cont):
120
     row_cont.set_size_request(10, 26)
121
     return row_cont
122
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/projectaction.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/projectaction.py Changed
201
 
1
@@ -29,6 +29,7 @@
2
 import os
3
 from os import listdir
4
 from os.path import isfile, join
5
+from PIL import Image
6
 import re
7
 import shutil
8
 import time
9
@@ -55,7 +56,9 @@
10
 from editorstate import PROJECT
11
 from editorstate import MONITOR_MEDIA_FILE
12
 import editorpersistance
13
+import medialinker
14
 import movemodes
15
+import mltprofiles
16
 import persistance
17
 import projectdata
18
 import projectinfogui
19
@@ -96,6 +99,7 @@
20
             editorstate.project_is_loading = True
21
             
22
             project = persistance.load_project(self.filename)
23
+
24
             sequence.set_track_counts(project)
25
             
26
             editorstate.project_is_loading = False
27
@@ -103,15 +107,29 @@
28
         except persistance.FileProducerNotFoundError as e:
29
             print "did not find file:", e
30
             self._error_stop(dialog, ticker)
31
+            Gdk.threads_enter()
32
             primary_txt = _("Media asset was missing!")
33
             secondary_txt = _("Path of missing asset:") + "\n   <b>" + e.value  + "</b>\n\n" + \
34
                             _("Relative search for replacement file in sub folders of project file failed.") + "\n\n" + \
35
                             _("To load the project you will need to either:") + "\n" + \
36
-                            u"\u2022" + " " + _("Use 'Media Linker' tool to relink media assets to new files, or") + "\n" + \
37
+                            u"\u2022" + " " + _("Open project in 'Media Relinker' tool to relink media assets to new files, or") + "\n" + \
38
                             u"\u2022" + " " + _("Place a file with the same exact name and path on the hard drive")
39
-            dialogutils.warning_message(primary_txt, secondary_txt, None, is_info=False)
40
+            open_label = Gtk.Label(_("Open project in Media Relinker tool"))
41
+            self.open_check = Gtk.CheckButton()
42
+            self.open_check.set_active(True)
43
+            check_row = Gtk.HBox(False, 1)
44
+            check_row.pack_start(Gtk.Label(), True, True, 0)
45
+            check_row.pack_start(self.open_check, False, False, 0)
46
+            check_row.pack_start(open_label, False, False, 0)
47
+            guiutils.set_margins(check_row,24,0,0,0)
48
+            panels = [check_row]
49
+            dialogutils.warning_message_with_panels(primary_txt, secondary_txt, 
50
+                                                    gui.editor_window.window, 
51
+                                                    False, self._missing_file_dialog_callback,
52
+                                                    panels)
53
             editorstate.project = old_project # persistance.load_project() changes this,
54
                                               # we simply change it back as no GUI or other state is yet changed
55
+            Gdk.threads_leave()
56
             return
57
         except persistance.ProjectProfileNotFoundError as e:
58
             self._error_stop(dialog, ticker)
59
@@ -152,8 +170,14 @@
60
         Gdk.threads_leave()
61
         ticker.stop_ticker()
62
 
63
-            
64
 
65
+    def _missing_file_dialog_callback(self, dialog, response_id):
66
+        if self.open_check.get_active() == True:
67
+            medialinker.display_linker(self.filename)
68
+            dialog.destroy()
69
+        else:
70
+            dialog.destroy()
71
+    
72
 class AddMediaFilesThread(threading.Thread):
73
     
74
     def __init__(self, filenames):
75
@@ -166,6 +190,7 @@
76
         gui.editor_window.window.get_window().set_cursor(watch)
77
         Gdk.threads_leave()
78
 
79
+        is_first_video_load = PROJECT().is_first_video_load()
80
         duplicates = []
81
         succes_new_file = None
82
         filenames = self.filenames
83
@@ -194,7 +219,7 @@
84
         # Update editor gui
85
         Gdk.threads_enter()
86
         gui.media_list_view.fill_data_model()
87
-        gui.bin_list_view.fill_data_model()
88
+        update_current_bin_files_count()
89
         _enable_save()
90
 
91
         normal_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR) #RTL
92
@@ -203,7 +228,10 @@
93
 
94
         if len(duplicates) > 0:
95
             GObject.timeout_add(10, _duplicates_info, duplicates)
96
-        
97
+
98
+        if is_first_video_load:
99
+            GObject.timeout_add(10, _first_load_profile_check)
100
+            
101
         audiowaveformrenderer.launch_audio_levels_rendering(filenames)
102
 
103
 def _duplicates_info(duplicates):
104
@@ -225,6 +253,27 @@
105
     dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
106
     return False
107
 
108
+def _first_load_profile_check():
109
+    for uid, media_file in PROJECT().media_files.iteritems():
110
+        if media_file.type == appconsts.VIDEO:
111
+            if media_file.matches_project_profile() == False:
112
+                dialogs.not_matching_media_info_dialog(PROJECT(), media_file, _not_matching_media_info_callback)
113
+                break
114
+
115
+def _not_matching_media_info_callback(dialog, response_id, media_file):
116
+    dialog.destroy()
117
+            
118
+    if response_id == Gtk.ResponseType.ACCEPT:
119
+        # Save in hidden and open
120
+        match_profile_index = mltprofiles.get_closest_matching_profile_index(media_file.info)
121
+        profile = mltprofiles.get_profile_for_index(match_profile_index)
122
+
123
+        path = utils.get_hidden_user_dir_path() + "/" + PROJECT().name
124
+
125
+        persistance.save_project(PROJECT(), path, profile.description()) #<----- HERE
126
+        
127
+        actually_load_project(path)
128
+
129
 def _load_pulse_bar():
130
     Gdk.threads_enter()
131
     try: 
132
@@ -302,10 +351,19 @@
133
 def _save_project_in_last_saved_path():
134
     updater.set_info_icon(Gtk.STOCK_SAVE)
135
 
136
-    PROJECT().events.append(projectdata.ProjectEvent(projectdata.EVENT_SAVED, PROJECT().last_save_path))
137
-
138
-    persistance.save_project(PROJECT(), PROJECT().last_save_path) #<----- HERE
139
+    try:
140
+        
141
+        persistance.save_project(PROJECT(), PROJECT().last_save_path) #<----- HERE
142
+        
143
+    except IOError as ioe:
144
+        updater.set_info_icon(None)
145
+        primary_txt = "I/O error({0})".format(ioe.errno)
146
+        secondary_txt = ioe.strerror + "."
147
+        dialogutils.warning_message(primary_txt, secondary_txt, gui.editor_window.window, is_info=False)
148
+        return
149
 
150
+    PROJECT().events.append(projectdata.ProjectEvent(projectdata.EVENT_SAVED, PROJECT().last_save_path))
151
+    
152
     global save_icon_remove_event_id
153
     save_icon_remove_event_id = GObject.timeout_add(500, remove_save_icon)
154
 
155
@@ -328,6 +386,18 @@
156
         PROJECT().name = unicode(os.path.basename(filenames[0]), "utf-8")
157
         updater.set_info_icon(Gtk.STOCK_SAVE)
158
 
159
+        try:
160
+            
161
+            persistance.save_project(PROJECT(), PROJECT().last_save_path) #<----- HERE
162
+            
163
+        except IOError as ioe:
164
+            dialog.destroy()
165
+            updater.set_info_icon(None)
166
+            primary_txt = "I/O error({0})".format(ioe.errno)
167
+            secondary_txt = ioe.strerror + "."
168
+            dialogutils.warning_message(primary_txt, secondary_txt, gui.editor_window.window, is_info=False)
169
+            return
170
+
171
         if len(PROJECT().events) == 0: # Save as... with 0 project events is considered Project creation
172
             p_event = projectdata.ProjectEvent(projectdata.EVENT_CREATED_BY_SAVING, PROJECT().last_save_path)
173
             PROJECT().events.append(p_event)
174
@@ -335,8 +405,6 @@
175
             p_event = projectdata.ProjectEvent(projectdata.EVENT_SAVED_AS, (PROJECT().name, PROJECT().last_save_path))
176
             PROJECT().events.append(p_event)
177
             
178
-        persistance.save_project(PROJECT(), PROJECT().last_save_path) #<----- HERE
179
-        
180
         app.stop_autosave()
181
         app.start_autosave()
182
         
183
@@ -389,6 +457,38 @@
184
     save_thread = SnaphotSaveThread(root_folder_path, project_name)
185
     save_thread.start()
186
 
187
+def change_project_profile():
188
+    dialogs.change_profile_project_dialog(PROJECT(), _change_project_profile_callback)
189
+
190
+def _change_project_profile_callback(dialog, response_id, profile_combo, out_folder, project_name_entry):
191
+    if response_id == Gtk.ResponseType.ACCEPT:
192
+        folder = "/" + out_folder.get_uri().lstrip("file:/")
193
+        name = project_name_entry.get_text()
194
+        profile = mltprofiles.get_profile_for_index(profile_combo.get_active())
195
+        path = folder + "/" + name
196
+        
197
+        persistance.save_project(PROJECT(), path, profile.description()) #<----- HERE
198
+
199
+        dialog.destroy()
200
+    else:
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/projectdata.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/projectdata.py Changed
165
 
1
@@ -35,6 +35,7 @@
2
 import appconsts
3
 import editorpersistance
4
 from editorstate import PLAYER
5
+from editorstate import PROJECT
6
 import mltprofiles
7
 import mltrefhold
8
 import patternproducer
9
@@ -120,12 +121,13 @@
10
         if media_type == appconsts.AUDIO:
11
             icon_path = respaths.IMAGE_PATH + "audio_file.png"
12
             length = thumbnailer.get_file_length(file_path)
13
+            info = None
14
         else: # For non-audio we need write a thumbbnail file and get file lengh while we're at it
15
-             (icon_path, length) = thumbnailer.write_image(file_path)
16
+             (icon_path, length, info) = thumbnailer.write_image(file_path)
17
 
18
-          # Create media file object
19
+        # Create media file object
20
         media_object = MediaFile(self.next_media_file_id, file_path, 
21
-                               file_name, media_type, length, icon_path)
22
+                               file_name, media_type, length, icon_path, info)
23
 
24
         self._add_media_object(media_object)
25
         
26
@@ -198,7 +200,7 @@
27
         self.sequences.append(seq)
28
         self.next_seq_number += 1
29
 
30
-    def get_filtered_media_log_events(self, group_index, incl_starred, incl_not_starred):
31
+    def get_filtered_media_log_events(self, group_index, incl_starred, incl_not_starred, sorting_order):
32
         filtered_events = []
33
         if group_index < 0:
34
             view_items = self.media_log
35
@@ -208,6 +210,12 @@
36
         for media_log_event in view_items:
37
             if self._media_log_included_by_starred(media_log_event.starred, incl_starred, incl_not_starred):
38
                 filtered_events.append(media_log_event)
39
+        
40
+        if sorting_order == appconsts.NAME_SORT:
41
+            filtered_events = sorted(filtered_events, key=lambda mevent: mevent.name)
42
+        elif sorting_order == appconsts.COMMENT_SORT:
43
+            filtered_events = sorted(filtered_events, key=lambda mevent: mevent.comment)
44
+
45
         return filtered_events
46
 
47
     def _media_log_included_by_starred(self, starred, incl_starred, incl_not_starred):
48
@@ -254,58 +262,20 @@
49
             return None
50
 
51
         return os.path.dirname(last_render_event.data)
52
-    """
53
-    not handled here anymore
54
-    # ------------------------------------------------------- Snapshot save project
55
-
56
-    def save_backup_snapshot(self, root_folder_path):
57
-        media_folder = root_folder_path +  "media/"
58
 
59
-        d = os.path.dirname(media_folder)
60
-        os.mkdir(d)
61
+    def is_first_video_load(self):
62
+        for uid, media_file in self.media_files.iteritems():
63
+            if media_file.type == appconsts.VIDEO:
64
+                return False
65
+        
66
+        return True
67
 
68
-        asset_paths = {}
69
 
70
-        # Copy media files
71
-        for idkey, media_file in self.media_files.items():
72
-            # Copy asset file and fix path
73
-            directory, file_name = os.path.split(media_file.path)
74
-            media_file_copy = media_folder + file_name
75
-            print media_file_copy, "out side"
76
-            if media_file_copy in asset_paths: # Create different filename for files 
77
-                                               # that have same filename but different path
78
-                print "in side"
79
-                file_name = self.get_unique_name(media_file.path, file_name)
80
-                media_file_copy = media_folder + file_name
81
-                
82
-            shutil.copyfile(media_file.path, media_file_copy)
83
-            asset_paths[media_file.path] = media_file_copy
84
-
85
-        # Copy clip producers paths
86
-        for seq in self.sequences:
87
-            for track in seq.tracks:
88
-                for i in range(0, len(track.clips)):
89
-                    clip = track.clips[i]
90
-                    # Only producer clips are affected
91
-                    if (clip.is_blanck_clip == False and (clip.media_type != appconsts.PATTERN_PRODUCER)):
92
-                        directory, file_name = os.path.split(clip.path)
93
-                        clip_file_copy = media_folder + file_name
94
-                        if not os.path.isfile(clip_file_copy):
95
-                            print "clip_file_copy", clip_file_copy
96
-                            shutil.copyfile(clip.path, clip_file_copy) # only rendered files are copied here
97
-                            asset_paths[clip.path] = clip_file_copy # This stuff is already md5 hashed, so no duplicate problems here
98
-
99
-
100
-    def get_unique_name(self, file_path, file_name):
101
-        (name, ext) = os.path.splitext(file_name)
102
-        return md5.new(file_path).hexdigest() + ext
103
-    """
104
-        
105
 class MediaFile:
106
     """
107
     Media file that can added to and edited in Sequence.
108
     """
109
-    def __init__(self, id, file_path, name, media_type, length, icon_path):
110
+    def __init__(self, id, file_path, name, media_type, length, icon_path, info):
111
         self.id = id
112
         self.path = file_path
113
         self.name = name
114
@@ -324,6 +294,8 @@
115
         
116
         self.current_frame = 0
117
 
118
+        self.info = info
119
+
120
         # Set default length for graphics files
121
         (f_name, ext) = os.path.splitext(self.name)
122
         if utils.file_extension_is_graphics_file(ext):
123
@@ -384,6 +356,23 @@
124
         self.path, self.second_file_path = self.second_file_path, self.path
125
         self.is_proxy_file = False
126
 
127
+    def matches_project_profile(self):
128
+        if (not hasattr(self, "info")): # to make really sure that old projects don't crash,
129
+            return True                            # but probably is not needed as attr is added at load
130
+        if self.info == None:
131
+            return True
132
+        
133
+        is_match = True # this is true for audio and graphics and image sequences and is only 
134
+                        # set false for video that does not match profile
135
+                        
136
+        if self.type == appconsts.VIDEO:
137
+            best_media_profile_index = mltprofiles.get_closest_matching_profile_index(self.info)
138
+            project_profile_index = mltprofiles.get_index_for_name(PROJECT().profile.description())
139
+            if best_media_profile_index != project_profile_index:
140
+                is_match = False
141
+        
142
+        return is_match
143
+        
144
 
145
 class BinColorClip:
146
     # DECPRECATED, this is replaced by patternproducer.BinColorClip.
147
@@ -454,6 +443,8 @@
148
         if producer.is_valid() == False:
149
             raise ProducerNotValidError(file_path)
150
 
151
+        info = utils.get_file_producer_info(producer)
152
+
153
         length = producer.get_length()
154
         frame = length / 2
155
         producer = producer.cut(frame, frame)
156
@@ -462,7 +453,7 @@
157
         consumer.connect(producer)
158
         consumer.run()
159
         
160
-        return (thumbnail_path, length)
161
+        return (thumbnail_path, length, info)
162
 
163
     def get_file_length(self, file_path):
164
         # This is used for audio files which don't need a thumbnail written
165
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/projectinfogui.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/projectinfogui.py Changed
9
 
1
@@ -28,7 +28,6 @@
2
 import guiutils
3
 import utils
4
 
5
-
6
 widgets = utils.EmptyClass()
7
 
8
 
9
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/propertyedit.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/propertyedit.py Changed
10
 
1
@@ -440,7 +440,7 @@
2
 class SingleKeyFrameProperty(EditableProperty):
3
     """
4
     Converts adjustments to expressions like "0=value" and
5
-    crates adjustments from expressions.
6
+    creates adjustments from expressions.
7
     """
8
     
9
     def get_input_range_adjustment(self):
10
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/propertyeditorbuilder.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/propertyeditorbuilder.py Changed
38
 
1
@@ -398,8 +398,8 @@
2
         
3
     dialog = Gtk.FileChooserDialog(_("Select Luma File"), None, 
4
                                    Gtk.FileChooserAction.OPEN, 
5
-                                   (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
6
-                                    _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT), None)
7
+                                   (_("Cancel").encode('utf-8'), Gtk.ResponseType.CANCEL,
8
+                                    _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
9
     dialog.set_action(Gtk.FileChooserAction.OPEN)
10
     dialog.set_select_multiple(False)
11
     file_filter = Gtk.FileFilter()
12
@@ -486,8 +486,10 @@
13
     hbox.pack_start(_get_boolean_check_box_button_column(_("Align"), aligned), False, False, 0)
14
     hbox.pack_start(_get_boolean_check_box_button_column(_("Distort"), distort), False, False, 0)
15
     hbox.pack_start(Gtk.Label(), True, True, 0)
16
-    hbox.pack_start(_get_combo_box_column(_("Alpha"), values, operator), False, False, 0)
17
-    hbox.pack_start(Gtk.Label(), True, True, 0)
18
+    # THESE ARE DISABLED BECAUSE CHANGING APLHA MODE CAN MAKE PROJECTS UNOPENABLE IF AFFECTED 
19
+    # COMPOSITOR IS ON THE FIRST FRAME
20
+    #hbox.pack_start(_get_combo_box_column(_("Alpha"), values, operator), False, False, 0)
21
+    #hbox.pack_start(Gtk.Label(), True, True, 0)
22
     hbox.pack_start(force_vbox, False, False, 0)
23
     hbox.pack_start(guiutils.get_pad_label(3, 5), False, False, 0)
24
     return hbox
25
@@ -578,8 +580,10 @@
26
     hbox.pack_start(guiutils.get_pad_label(3, 5), False, False, 0)
27
     hbox.pack_start(_get_boolean_check_box_button_column(_("Align"), aligned), False, False, 0)
28
     hbox.pack_start(_get_boolean_check_box_button_column(_("Distort"), distort), False, False, 0)
29
-    hbox.pack_start(Gtk.Label(), True, True, 0)
30
-    hbox.pack_start(_get_combo_box_column(_("Alpha"), values, operator), False, False, 0)
31
+    # THESE ARE DISABLED BECAUSE CHANGING APLHA MODE CAN MAKE PROJECTS UNOPENABLE IF THE AFFECTED 
32
+    # COMPOSITOR IS ON THE FIRST FRAME
33
+    #hbox.pack_start(Gtk.Label(), True, True, 0)
34
+    #hbox.pack_start(_get_combo_box_column(_("Alpha"), values, operator), False, False, 0)
35
     hbox.pack_start(Gtk.Label(), True, True, 0)
36
     hbox.pack_start(force_vbox, False, False, 0)
37
     hbox.pack_start(guiutils.get_pad_label(3, 5), False, False, 0)
38
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/proxyediting.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/proxyediting.py Changed
39
 
1
@@ -159,7 +159,7 @@
2
         # If we're currently proxy editing, we need to update 
3
         # all the clips on the timeline to use proxy media.
4
         if editorstate.PROJECT().proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA:
5
-            _auto_renconvert_after_proxy_render_in_proxy_mode()
6
+            _auto_re_convert_after_proxy_render_in_proxy_mode()
7
         
8
         print "proxy render done"
9
 
10
@@ -692,7 +692,10 @@
11
     load_thread = ProxyProjectLoadThread(conv_temp_project_path, manager_window.convert_progress_bar)
12
     load_thread.start()
13
 
14
-def _auto_renconvert_after_proxy_render_in_proxy_mode():
15
+def _auto_re_convert_after_proxy_render_in_proxy_mode():
16
+
17
+    editorstate.project_is_loading = True
18
+
19
     # Save to temp to convert to using original media
20
     project = editorstate.PROJECT()
21
     project.proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_ORIGINAL_MEDIA
22
@@ -707,11 +710,13 @@
23
     # Save to temp to convert back to using proxy media
24
     project.proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_PROXY_MEDIA
25
     persistance.save_project(project, conv_temp_project_path)
26
-    project.proxy_data.proxy_mode = appconsts.USE_PROXY_MEDIA
27
-
28
+    
29
     # Load saved temp proxy project
30
     project = persistance.load_project(conv_temp_project_path)
31
-
32
+    project.proxy_data.proxy_mode = appconsts.USE_PROXY_MEDIA
33
+        
34
+    editorstate.project_is_loading = False
35
+            
36
     # Open saved temp project
37
     app.stop_autosave()
38
 
39
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/render.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/render.py Changed
157
 
1
@@ -45,8 +45,6 @@
2
 import guiutils
3
 import mltprofiles
4
 import mltrefhold
5
-import projectdata
6
-import projectinfogui
7
 import renderconsumer
8
 import rendergui
9
 import sequence
10
@@ -97,122 +95,7 @@
11
         PLAYER().set_render_callbacks(callbacks)
12
         PLAYER().start_rendering(self.render_consumer, self.start_frame, self.end_frame)
13
 
14
-"""
15
-def render_timeline():
16
-    if len(widgets.file_panel.movie_name.get_text()) == 0:
17
-        primary_txt = _("Render file name entry is empty")
18
-        secondary_txt = _("You have to provide a name for the file to be rendered.")
19
-        dialogutils.warning_message(primary_txt, secondary_txt, gui.editor_window.window)
20
-        return   
21
-
22
-    if os.path.exists(get_file_path()):
23
-        primary_txt = _("File: ") + get_file_path() + _(" already exists!")
24
-        secondary_txt = _("Do you want to overwrite existing file?")
25
-        dialogutils.warning_confirmation(_render_overwrite_confirm_callback, primary_txt, secondary_txt, gui.editor_window.window)
26
-    else:
27
-        _do_rendering()
28
-
29
-def _render_overwrite_confirm_callback(dialog, response_id):
30
-    dialog.destroy()
31
-    
32
-    if response_id == Gtk.ResponseType.ACCEPT:
33
-        _do_rendering()
34
-
35
-def _do_rendering():
36
-    print "timeline render..."
37
-    
38
-    global aborted
39
-    aborted = False
40
-    render_consumer = get_render_consumer()
41
-    if render_consumer == None:
42
-        return
43
-
44
-    # Set render start and end points
45
-    if widgets.range_cb.get_active() == 0:
46
-        start_frame = 0
47
-        end_frame = -1 # renders till finish
48
-    else:
49
-        start_frame = current_sequence().tractor.mark_in
50
-        end_frame = current_sequence().tractor.mark_out
51
-
52
-    # Only render a range if it is defined.
53
-    if start_frame == -1 or end_frame == -1:
54
-        if widgets.range_cb.get_active() == 1:
55
-            rendergui.no_good_rander_range_info()
56
-            return
57
-
58
-    file_path = get_file_path()
59
-    project_event = projectdata.ProjectEvent(projectdata.EVENT_RENDERED, file_path)
60
-    PROJECT().events.append(project_event)
61
-    projectinfogui.update_project_info()
62
-
63
-    # See if project and render fps match
64
-    cnum = render_consumer.profile().frame_rate_num()
65
-    cden = render_consumer.profile().frame_rate_den()
66
-    pnum = PROJECT().profile.frame_rate_num()
67
-    pden = PROJECT().profile.frame_rate_den()
68
-    
69
-    if (cnum == pnum) and (cden == pden):
70
-        frames_rates_match = True
71
-    else:
72
-        frames_rates_match = False
73
-
74
-    global progress_window
75
-    progress_window = rendergui.render_progress_dialog(_render_cancel_callback,
76
-                                                       gui.editor_window.window,
77
-                                                       frames_rates_match)
78
-                                                       
79
-    set_render_gui()
80
-
81
-    render_launch = RenderLauncher(render_consumer, start_frame, end_frame)
82
-    render_launch.start()
83
-
84
-def _render_cancel_callback(dialog, response_id):
85
-    global aborted
86
-    aborted = True
87
-    dialog.destroy()
88
-    PLAYER().consumer.stop()
89
-    PLAYER().producer.set_speed(0)
90
-"""
91
-
92
-# -------------------------------------------------- render consumer
93
-def get_render_consumer():
94
-    file_path = get_file_path()
95
-    if file_path == None:
96
-        return None
97
-
98
-    profile = get_current_profile()
99
 
100
-    if widgets.render_type_panel.type_combo.get_active() == 1: # Preset encodings
101
-        encoding_option = renderconsumer.non_user_encodings[widgets.render_type_panel.presets_selector.widget.get_active()]
102
-        if encoding_option.type != "img_seq":
103
-            consumer = renderconsumer.get_render_consumer_for_encoding(file_path,
104
-                                                                       profile,
105
-                                                                       encoding_option)
106
-        else: # Image Sequence rendering consumers need to be created a bit differently
107
-            consumer = renderconsumer.get_img_seq_render_consumer(file_path,
108
-                                                                  profile,
109
-                                                                  encoding_option)
110
-        return consumer
111
-
112
-    if widgets.args_panel.use_args_check.get_active() == False:
113
-        # Using options comboboxes
114
-        encoding_option_index = widgets.encoding_panel.encoding_selector.widget.get_active()
115
-        quality_option_index = widgets.encoding_panel.quality_selector.widget.get_active()
116
-        consumer = renderconsumer.get_render_consumer_for_encoding_and_quality( file_path,
117
-                                                                                profile,
118
-                                                                                encoding_option_index,
119
-                                                                                quality_option_index)
120
-    else:
121
-        buf = widgets.args_panel.opts_view.get_buffer()
122
-        consumer, error = renderconsumer.get_render_consumer_for_text_buffer(file_path,
123
-                                                                             profile,
124
-                                                                             buf)
125
-        if error != None:
126
-            dialogutils.warning_message("FFMPeg Args Error", error, gui.editor_window.window)
127
-            return None
128
-        
129
-    return consumer
130
 
131
 def get_args_vals_list_for_current_selections():
132
     profile = get_current_profile()
133
@@ -443,8 +326,8 @@
134
 
135
 # ------------------------------------------------------------- framebuffer clip rendering
136
 # Rendering a slow/fast motion version of media file.
137
-def render_frame_buffer_clip(media_file):
138
-    rendergui.show_slowmo_dialog(media_file, _render_frame_buffer_clip_dialog_callback)
139
+def render_frame_buffer_clip(media_file, default_range_render=False):
140
+    rendergui.show_slowmo_dialog(media_file, default_range_render, _render_frame_buffer_clip_dialog_callback)
141
 
142
 def _render_frame_buffer_clip_dialog_callback(dialog, response_id, fb_widgets, media_file):
143
     if response_id == Gtk.ResponseType.ACCEPT:
144
@@ -479,7 +362,11 @@
145
         dialog.destroy()
146
 
147
         # Create motion producer
148
-        fr_path = "framebuffer:" + media_file.path + "?" + str(speed)
149
+        source_path = media_file.path
150
+        if media_file.is_proxy_file == True:
151
+            source_path = media_file.second_file_path
152
+
153
+        fr_path = "framebuffer:" + source_path + "?" + str(speed)
154
         motion_producer = mlt.Producer(profile, None, str(fr_path))
155
         mltrefhold.hold_ref(motion_producer)
156
         
157
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/renderconsumer.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/renderconsumer.py Changed
40
 
1
@@ -220,7 +220,7 @@
2
             msg = "...NOT available, " + encoding_option.err_msg + " missing"
3
             not_supported_encoding_options.append(encoding_option)
4
             print encoding_option.name + msg
5
-    
6
+
7
     # Proxy encoding
8
     proxy_encoding_nodes = render_encoding_doc.getElementsByTagName(PROXY_ENCODING_OPTION)
9
     found_proxy_encodings = []
10
@@ -306,23 +306,13 @@
11
     
12
     return args_vals_list
13
 
14
-"""
15
-def get_args_vals_tuples_list_for_encoding_option(profile, encoding_option):
16
-    encoding_option = encoding_options[enc_opt_index]
17
-    if quality_opt_index >= 0:
18
-        quality_option = encoding_option.quality_options[quality_opt_index]
19
-    else:
20
-        quality_option = None
21
+def get_video_non_user_encodigs():
22
+    video_non_user_encs = []
23
+    for enc in non_user_encodings:
24
+        if enc.type != "audio":
25
+            video_non_user_encs.append(enc)
26
 
27
-    args_vals_list = encoding_option.get_args_vals_tuples_list(profile, quality_option)
28
-
29
-    # Quality options  key, value list
30
-    if quality_option != None:
31
-        for k, v in quality_option.add_map.iteritems():
32
-            args_vals_list.append((str(k), str(v)))
33
-    
34
-    return args_vals_list
35
-"""
36
+    return video_non_user_encs
37
 
38
 def get_ffmpeg_opts_args_vals_tuples_list(buf):
39
     end = buf.get_end_iter()
40
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/rendergui.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/rendergui.py Changed
65
 
1
@@ -99,8 +99,8 @@
2
 def load_ffmpeg_opts_dialog(callback, opts_extension):
3
     dialog = Gtk.FileChooserDialog(_("Load Render Args File"), None, 
4
                                    Gtk.FileChooserAction.OPEN, 
5
-                                   (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
6
-                                    _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT), None)
7
+                                   (_("Cancel").encode('utf-8'), Gtk.ResponseType.CANCEL,
8
+                                    _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
9
     dialog.set_action(Gtk.FileChooserAction.OPEN)
10
     dialog.set_select_multiple(False)
11
     file_filter = Gtk.FileFilter()
12
@@ -113,8 +113,8 @@
13
 def save_ffmpeg_opts_dialog(callback, opts_extension):
14
     dialog = Gtk.FileChooserDialog(_("Save Render Args As"), None, 
15
                                    Gtk.FileChooserAction.SAVE, 
16
-                                   (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
17
-                                   _("Save").encode('utf-8'), Gtk.ResponseType.ACCEPT), None)
18
+                                   (_("Cancel").encode('utf-8'), Gtk.ResponseType.CANCEL,
19
+                                   _("Save").encode('utf-8'), Gtk.ResponseType.ACCEPT))
20
     dialog.set_action(Gtk.FileChooserAction.SAVE)
21
     dialog.set_current_name("untitled" + opts_extension)
22
     dialog.set_do_overwrite_confirmation(True)
23
@@ -158,8 +158,11 @@
24
     dialog.show()
25
     return dialog
26
 
27
-def show_slowmo_dialog(media_file, _response_callback):
28
+def show_slowmo_dialog(media_file, default_range_render, _response_callback):
29
     folder, file_name = os.path.split(media_file.path)
30
+    if media_file.is_proxy_file:
31
+        folder, file_name = os.path.split(media_file.second_file_path)
32
+
33
     name, ext = os.path.splitext(file_name)
34
         
35
     dialog = Gtk.Dialog(_("Render Slow/Fast Motion Video File"), gui.editor_window.window,
36
@@ -250,7 +253,10 @@
37
     fb_widgets.render_range.pack_start(renderer_text, True)
38
     fb_widgets.render_range.add_attribute(renderer_text, "text", 0)
39
     fb_widgets.render_range.add_attribute(renderer_text, 'sensitive', 1)
40
-    fb_widgets.render_range.set_active(0)
41
+    if default_range_render == False:
42
+        fb_widgets.render_range.set_active(0)
43
+    else:
44
+        fb_widgets.render_range.set_active(1)
45
     fb_widgets.render_range.show()
46
 
47
     # To update rendered length display
48
@@ -263,7 +269,7 @@
49
     vbox = Gtk.VBox(False, 2)
50
     vbox.pack_start(mf_row, False, False, 0)
51
     vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark In: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_in]), False, False, 0)
52
-    vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source_Mark Out: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_out]), False, False, 0)
53
+    vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark Out: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_out]), False, False, 0)
54
     vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
55
     vbox.pack_start(hbox, False, False, 0)
56
     vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
57
@@ -496,6 +502,7 @@
58
     return render_panel
59
 
60
 
61
+    
62
 class RenderFilePanel():
63
 
64
     def __init__(self):
65
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/audio_levels_menu_launch.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/audio_levels_menu_launch.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/delete_range.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/flowblade_splash_black_small.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/flowblade_splash_black_small.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/flowbladetoolicon.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/hamburger.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/keyb_trim.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/log_range.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/log_range.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_in_label.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_in_label.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_in_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_in_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_in_very_small.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_in_very_small.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_out_label.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_out_label.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_out_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/mark_out_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/marks_clear_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/marks_clear_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/marks_length_label.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/marks_length_label.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/monitor_indicator.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/monitor_indicator.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/next_frame_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/next_frame_s.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/open_gmic.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/open_renderqueue.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/play_2_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/play_2_s.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/play_pause_s.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/prev_frame_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/prev_frame_s.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/profile_warning.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/redo.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/redo.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/snap_magnet.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/split_audio.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/to_mark_in_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/to_mark_in_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/to_mark_out_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/to_mark_out_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/track_video_mute.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/track_video_mute.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/transition_right.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/transition_wrong.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/darktheme/undo.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/darktheme/undo.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/gmic Added
2
 
1
+(directory)
2
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/gmic/gmicscripts.xml Added
201
 
1
@@ -0,0 +1,2565 @@
2
+<gmic>
3
+    
4
+    <gmicscript>
5
+        <name>Charcoal</name>
6
+        <group>Black and White</group>
7
+        <script>-gimp_charcoal 65,70,170,0,1,0,50,70,255,255,255,0,0,0,0,0</script>
8
+    </gmicscript>
9
+    
10
+    <gmicscript>
11
+        <name>Glow 2</name>
12
+        <group>Glow</group>
13
+        <script>-glow 10%</script>
14
+    </gmicscript>
15
+
16
+    <gmicscript>
17
+        <name>Pencil Portrait</name>
18
+        <group>Drawing</group>
19
+        <script>-gimp_pencil_portraitbw 30,120,1,0.5,144,79,21,0</script>
20
+    </gmicscript>
21
+
22
+    <gmicscript>
23
+        <name>Ink Wash</name>
24
+        <group>Black and White</group>
25
+        <script>-gimp_ink_wash 0.14,23,0,0.5,0.54,2.25,0,2,6,5,20</script>
26
+    </gmicscript>
27
+
28
+    <gmicscript>
29
+        <name>Dither BW</name>
30
+        <group>Black and White</group>
31
+        <script>-ditheredbw</script>
32
+    </gmicscript>
33
+    
34
+    <gmicscript>
35
+        <name>Angular Blur</name>
36
+        <group>Blur</group>
37
+        <script>-blur_angular 10</script>
38
+    </gmicscript>
39
+
40
+    <gmicscript>
41
+        <name>Rodilius</name>
42
+        <group>Glow</group>
43
+        <script>-rodilius 20,5,200,17,2,1</script>
44
+    </gmicscript>
45
+
46
+    <gmicscript>
47
+        <name>Cartoon</name>
48
+        <group>Painting</group>
49
+        <script>-cartoon 3,200,20,0.25,1.5,8,0</script>
50
+    </gmicscript>
51
+    
52
+    <gmicscript>
53
+        <name>Circlism</name>
54
+        <group>Painting</group>
55
+        <script>-gimp_circle_abstraction 8,5,0.8,0,1,1,1,0</script>
56
+    </gmicscript>
57
+
58
+    <gmicscript>
59
+        <name>Poster Hope</name>
60
+        <group>Painting</group>
61
+        <script>-gimp_poster_hope 0,3,0</script>
62
+    </gmicscript>
63
+
64
+    <gmicscript>
65
+        <name>Polygonize</name>
66
+        <group>Geometric</group>
67
+        <script>-gimp_polygonize 300,10,10,10,10,0,0,0,255,0</script>
68
+    </gmicscript>
69
+
70
+    <gmicscript>
71
+        <name>Pen Drawing</name>
72
+        <group>Drawing</group>
73
+        <script>-gimp_pen_drawing 10,0</script>
74
+    </gmicscript>
75
+
76
+    <gmicscript>
77
+        <name>Feltpen</name>
78
+        <group>Drawing</group>
79
+        <script>-gimp_feltpen 300,50,1,0.1,20,5,0</script>
80
+    </gmicscript>
81
+
82
+    <gmicscript>
83
+        <name>Fractalize</name>
84
+        <group>Special Effect</group>
85
+        <script>-fractalize 0.8</script>
86
+    </gmicscript>
87
+
88
+    <gmicscript>
89
+        <name>Rotate Tiles</name>
90
+        <group>Transform</group>
91
+        <script>-gimp_rotate_tiles 5,5,15,3,3,1.8</script>
92
+    </gmicscript>
93
+
94
+    <gmicscript>
95
+        <name>Shift Tiles</name>
96
+        <group>Transform</group>
97
+        <script>-gimp_shift_tiles 10,10,10,1</script>
98
+    </gmicscript>
99
+    
100
+    <gmicscript>
101
+        <name>Imagegrid</name>
102
+        <group>Transform</group>
103
+        <script>-gimp_imagegrid 10,10</script>
104
+    </gmicscript>
105
+
106
+    <gmicscript>
107
+        <name>Whirl</name>
108
+        <group>Artistic</group>
109
+        <script>-draw_whirl 20,0</script>
110
+    </gmicscript>
111
+
112
+    <gmicscript>
113
+        <name>Warhol</name>
114
+        <group>Painting</group>
115
+        <script>-warhol 3,3,2,40</script>
116
+    </gmicscript>
117
+    
118
+    <gmicscript>
119
+        <name>Shapeism</name>
120
+        <group>Geometric</group>
121
+        <script>-gimp_shapeism 2,7,0.38,0,1,5,32,8,3,1,5,0.5,1,0,0,0,255</script>
122
+    </gmicscript>
123
+
124
+    <gmicscript>
125
+        <name>Poster Edges</name>
126
+        <group>Edges</group>
127
+        <script>-gimp_poster_edges 20,60,5,0,10,0,0,0</script>
128
+    </gmicscript>
129
+
130
+    <gmicscript>
131
+        <name>Delaunay</name>
132
+        <group>Geometric</group>
133
+        <script>-gimp_delaunay 5,75,1,3,0,0,0,128,1,1,0</script>
134
+    </gmicscript>
135
+
136
+    <gmicscript>
137
+        <name>Painting</name>
138
+        <group>Painting</group>
139
+        <script>-gimp_painting 5,2.5,1.5,50,1,0</script>
140
+    </gmicscript>
141
+
142
+    <gmicscript>
143
+        <name>Lylejk</name>
144
+        <group>Painting</group>
145
+        <script>-gimp_lylejk_painting 10,2,4,10,0</script>
146
+    </gmicscript>
147
+
148
+    <gmicscript>
149
+        <name>Kuwahara</name>
150
+        <group>Painting</group>
151
+        <script>-gimp_kuwahara 2,5,0,0,0</script>
152
+    </gmicscript>
153
+
154
+    <gmicscript>
155
+        <name>Color Abstraction</name>
156
+        <group>Painting</group>
157
+        <script>-gimp_color_abstraction 1,10,0.2,0</script>
158
+    </gmicscript>
159
+
160
+    <gmicscript>
161
+        <name>Stamp</name>
162
+        <group>Black and White</group>
163
+        <script>-gimp_stamp 1,50,0,0,0,0,1,0</script>
164
+    </gmicscript>
165
+
166
+    <gmicscript>
167
+        <name>Sketch</name>
168
+        <group>Drawing</group>
169
+        <script>-gimp_sketchbw 2,45,180,30,1,0.03,0,0.6,0.1,0.6,0.25,1,0,1,0,0</script>
170
+    </gmicscript>
171
+
172
+    <gmicscript>
173
+        <name>PencilBW</name>
174
+        <group>Black and White</group>
175
+        <script>-gimp_pencilbw 0.3,60,0,0,0</script>
176
+    </gmicscript>
177
+
178
+    <gmicscript>
179
+        <name>Hough Sketch</name>
180
+        <group>Black and White</group>
181
+        <script>-gimp_houghsketchbw 1.25,10,5,80,0.1,0,0</script>
182
+    </gmicscript>
183
+
184
+    <gmicscript>
185
+        <name>Hard Sketch</name>
186
+        <group>Drawing</group>
187
+        <script>-gimp_hardsketchbw 300,50,1,0.1,20,0,0,0</script>
188
+    </gmicscript>
189
+
190
+    <gmicscript>
191
+        <name>Engrave</name>
192
+        <group>Black and White</group>
193
+        <script>-gimp_engrave 0.5,50,0,8,40,0,0,0,10,1,0,0,0,1,0</script>
194
+    </gmicscript>
195
+
196
+    <gmicscript>
197
+        <name>Segment Watershed</name>
198
+        <group>Painting</group>
199
+        <script>-gimp_segment_watershed 2,1,0,0,0</script>
200
+    </gmicscript>
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/help/tools.html -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/help/tools.html Changed
39
 
1
@@ -54,6 +54,37 @@
2
 <li> When relinking a project you have open in Flowblade at the same time make sure that do not overwrite the relinked version of project when saving the project you have open in Flowblade</li>
3
 </ol>
4
 
5
+<h3> G'Mic Effects</h3>
6
+<p>
7
+G'MIC is a full-featured open-source framework for image processing.
8
+</p>
9
+<p>
10
+Flowblade G'MIC tool presents user with a selection of commads that can be used to achieve complex filtering of video clips.</p>
11
+<p>
12
+<b>NOTE: If a command is not present in the system then the corresponding filtering selection will not work.</b>
13
+</p>
14
+<p>
15
+Commands are mostly embedded in the <b>/usr/bin/gmic</b> binary itself, so to have access to more commands you will mostly need to upgrade the binary in your system.
16
+</p>
17
+<p>
18
+It is however possible to add and use custom commands and use them for video filtering, <a href="  http://gmic.eu/reference.shtml#section11">more info here.</a>
19
+</p>
20
+
21
+<h4>Loading clip and rendering previews</h4>
22
+<ul>
23
+<li> Start by pressing <b>Load Clip</b> button, and select the video clip you wish to apply filtering on.</li>
24
+<li> Press on the downward triangle on top of the <b>Script Edit Area</b> on the left middle of the window to select a gmic command.</li>
25
+<li> You can alter the values given to commands in the <b>Script Edit Area</b>.</li>
26
+<li> Press the <b>Preview</b> button on the right middle to view the filtered image.</li>
27
+<li> After rendering preview the area below <b>Script Edit Area</b> shows text output from gmic with possible error messages.</li>
28
+<li> You can apply multiple commands by checking <b>Add to script</b> checkbox.</li>
29
+</ul>
30
+<h4>Rendering Output</h4>
31
+<ul>
32
+<li> To render a frame sequence you will need to set <b>Mark In and Mark out points</b> and  <b>select a folder</b> to hold the rendered frame sequence.</li>
33
+<li> To render a video file from the filtered frame sequence, check <b>Encode video</b> checkbox and press the <b>Encoding Settings</b> button to set properties of the rendered video file.</li>
34
+</ul>
35
+
36
 </div>
37
 </div>
38
 </body>
39
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/help/translations -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/help/translations Changed
17
 
1
@@ -1,8 +1,8 @@
2
 Translations by:
3
-   cs - Pavel Fric
4
-   fi - jl
5
-   fr - Loïc Vanderstichelen
6
-   de - Martin A. Wielebinski
7
-   es - David Gamiz Jimenez
8
-   it - Massimo Stella
9
-
10
+  cs - Pavel Fric
11
+  fi - jl
12
+  fr - Loïc Vanderstichelen
13
+  de - Martin A. Wielebinski
14
+  es - David Gamiz Jimenez
15
+  it - Massimo Stella
16
+  hu - Péter Gábor
17
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/audio_levels_menu_launch.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/audio_levels_menu_launch.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/delete_range.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/flowblade_splash_black_small.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/flowblade_splash_black_small.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/flowbladetoolicon.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/hamburger.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/keyb_trim.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/log_range.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/log_range.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/mark_in_label.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/mark_in_label.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/mark_in_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/mark_in_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/mark_in_very_small.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/mark_in_very_small.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/mark_out_label.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/mark_out_label.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/mark_out_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/mark_out_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/marks_clear_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/marks_clear_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/marks_length_label.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/marks_length_label.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/next_frame_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/next_frame_s.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/open_gmic.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/open_renderqueue.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/play_2_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/play_2_s.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/play_pause_s.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/prev_frame_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/prev_frame_s.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/profile_warning.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/redo.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/redo.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/snap_magnet.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/split_audio.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/to_mark_in_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/to_mark_in_s.png Changed
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/to_mark_out_s.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/to_mark_out_s.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/transition_right.png Added
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/transition_wrong.png Added
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/res/img/undo.png -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/img/undo.png Changed
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/res/profiles/atsc_1080p_60 Added
13
 
1
@@ -0,0 +1,11 @@
2
+description=HD 1080p 60 fps
3
+frame_rate_num=60
4
+frame_rate_den=1
5
+width=1920
6
+height=1080
7
+progressive=1
8
+sample_aspect_num=1
9
+sample_aspect_den=1
10
+display_aspect_num=16
11
+display_aspect_den=9
12
+colorspace=709
13
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/respaths.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/respaths.py Changed
29
 
1
@@ -39,14 +39,16 @@
2
 ROOT_PARENT = None
3
 PATTERN_PRODUCER_PATH = None
4
 LAUNCH_DIR = None
5
-
6
+GMIC_SCRIPTS_DOC = None
7
+PHANTOM_JAR = None
8
 
9
 def set_paths(root_path):
10
     global ROOT_PATH, IMAGE_PATH, THUMBNAIL_PATH, PROFILE_PATH,\
11
     BLACK_IMAGE_PATH, FILTERS_XML_DOC, COMPOSITORS_XML_DOC, \
12
     WIPE_RESOURCES_PATH, PREFS_PATH, HELP_DOC, LOCALE_PATH, \
13
     GPL_3_DOC, ROOT_PARENT, PATTERN_PRODUCER_PATH, TRANSLATIONS_DOC, \
14
-    LAUNCH_DIR, REPLACEMENTS_XML_DOC #, PROXY_PROFILE_PATH
15
+    LAUNCH_DIR, REPLACEMENTS_XML_DOC, GMIC_SCRIPTS_DOC,  \
16
+    PHANTOM_JAR, PHANTOM_DIR
17
     
18
     ROOT_PATH = root_path
19
     IMAGE_PATH = root_path + "/res/img/"
20
@@ -64,6 +66,8 @@
21
     ROOT_PARENT = ROOT_PATH.strip("Flowblade")
22
     PATTERN_PRODUCER_PATH = root_path + "/res/patternproducer/"
23
     LAUNCH_DIR = root_path + "/launch/"
24
+    GMIC_SCRIPTS_DOC = root_path + "/res/gmic/gmicscripts.xml"
25
+    PHANTOM_JAR = root_path + "/phantom2d/Phantom2D.jar"
26
 
27
 def apply_dark_theme():
28
     global IMAGE_PATH
29
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/sequence.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/sequence.py Changed
42
 
1
@@ -87,6 +87,9 @@
2
 # Track that all audio is mixed down to combine for output.
3
 AUDIO_MIX_DOWN_TRACK = 0
4
 
5
+# Vectorscop and RGB Parade
6
+SCOPE_MIX_VALUES = [1.0, 0.8, 0.5, 0.2, 0.0]
7
+_scope_over_lay_mix = 2
8
 
9
 class Sequence:
10
     """
11
@@ -139,11 +142,11 @@
12
         
13
         self.vectorscope = mlt.Filter(self.profile, "frei0r.vectorscope")
14
         mltrefhold.hold_ref(self.vectorscope) # ?? is this just some anti-crash hack attempt that was not removed
15
-        self.vectorscope.set("mix", "0.5")
16
+        self.vectorscope.set("mix", str(SCOPE_MIX_VALUES[_scope_over_lay_mix]))
17
         self.vectorscope.set("overlay sides", "0.0") 
18
         self.rgbparade =  mlt.Filter(self.profile, "frei0r.rgbparade")
19
         mltrefhold.hold_ref(self.rgbparade) # ?? is this just some anti-crash hack attempt that was not removed
20
-        self.rgbparade.set("mix", "0.4")
21
+        self.rgbparade.set("mix", str(SCOPE_MIX_VALUES[_scope_over_lay_mix]))
22
         self.rgbparade.set("overlay sides", "0.0")
23
         self.outputfilter = None
24
 
25
@@ -749,6 +752,16 @@
26
             self.tractor.attach(self.rgbparade)
27
             self.outputfilter = self.rgbparade
28
 
29
+    def set_scope_overlay_mix(self, mix_value_index):
30
+        global _scope_over_lay_mix
31
+        _scope_over_lay_mix = mix_value_index
32
+
33
+        self.vectorscope.set("mix", str(SCOPE_MIX_VALUES[_scope_over_lay_mix]))
34
+        self.rgbparade.set("mix", str(SCOPE_MIX_VALUES[_scope_over_lay_mix]))
35
+
36
+    def get_mix_index(self):
37
+        return _scope_over_lay_mix
38
+
39
     # ---------------------------------------------------- watermark
40
     def add_watermark(self, watermark_file_path):
41
         watermark = mlt.Filter(self.profile, "watermark")
42
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/snapping.py Added
184
 
1
@@ -0,0 +1,182 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor. If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+"""
23
+This module handles snapping to clip ends while mouse dragging on timeline.
24
+"""
25
+
26
+import appconsts
27
+import compositormodes
28
+import editorstate
29
+from editorstate import current_sequence
30
+from editorstate import EDIT_MODE
31
+
32
+# These are monkeypatched to haev acces to tlinewidgets.py state  
33
+_get_frame_for_x_func = None
34
+_get_x_for_frame_func = None
35
+
36
+snapping_on = True
37
+show_magnet_icon = True
38
+
39
+_snap_threshold = 6 # in pixels
40
+
41
+_snap_happened = False
42
+_last_snap_x = -1
43
+
44
+
45
+#---------------------------------------------------- interface
46
+def get_snapped_x(x, track, edit_data):
47
+    if snapping_on == False:
48
+        return x
49
+    
50
+    frame = _get_frame_for_x_func(x)
51
+
52
+    # Do snaps for relevant edit modes.
53
+    if EDIT_MODE() == editorstate.OVERWRITE_MOVE:
54
+        return _overwrite_move_snap(x, track, frame, edit_data)
55
+    elif EDIT_MODE() == editorstate.CLIP_END_DRAG:
56
+        return _object_end_drag_snap(x, track, frame, edit_data)
57
+    elif EDIT_MODE() == editorstate.COMPOSITOR_EDIT:
58
+        track = current_sequence().tracks[compositormodes.compositor.transition.b_track - 1]
59
+        if compositormodes.sub_mode == compositormodes.TRIM_EDIT:
60
+            return _object_end_drag_snap(x, track, frame, edit_data)
61
+        elif compositormodes.sub_mode == compositormodes.MOVE_EDIT:
62
+            return _compositor_move_snap(x, track, frame, edit_data)
63
+
64
+    # Many edit modes do not have snapping even if snapping is on
65
+    return x
66
+
67
+def snap_active():
68
+    return _snap_happened
69
+
70
+def get_snap_x():
71
+    return _last_snap_x
72
+
73
+def mouse_edit_ended():
74
+    global _snap_happened
75
+    _snap_happened = False
76
+
77
+
78
+#------------------------------------------- utils funcs
79
+def _get_track_above(track):
80
+    if track.id < len(current_sequence().tracks) - 2:
81
+        return current_sequence().tracks[track.id  + 1]
82
+    else:
83
+        return None
84
+        
85
+def _get_track_below(track):
86
+    if track.id > 1:
87
+        return current_sequence().tracks[track.id  - 1]
88
+    else:
89
+        return None
90
+
91
+def _get_track_snapped_x(track, x, frame, frame_x):
92
+    closest_cut_frame = current_sequence().get_closest_cut_frame(track.id, frame)
93
+    if closest_cut_frame == -1:
94
+        return -1
95
+    
96
+    cut_frame_x = _get_x_for_frame_func(closest_cut_frame)
97
+    
98
+    if abs(cut_frame_x - frame_x) < _snap_threshold:
99
+        global _last_snap_x
100
+        _last_snap_x = cut_frame_x
101
+        return x - (frame_x - cut_frame_x)
102
+    else:
103
+        return -1 # no snapping happened
104
+
105
+def _three_track_snap(track, x, frame, frame_x):
106
+    snapped_x = -1
107
+    
108
+    track_above = _get_track_above(track)
109
+    track_below = _get_track_below(track)
110
+    
111
+    # Check snapping for mouse track and the tracks beside mouse track
112
+    # Check order: track_above, track_below, track, last in order is preferred if multiple snapping happens
113
+    if track_above != None:
114
+        snapped_x = _get_track_snapped_x(track_above, x, frame, frame_x)
115
+    if track_below != None:
116
+        snapped_next_track_x = _get_track_snapped_x(track_below, x, frame, frame_x)
117
+        if snapped_next_track_x != -1:
118
+            snapped_x = snapped_next_track_x
119
+    snapped_next_track_x = _get_track_snapped_x(track, x, frame, frame_x)
120
+    if snapped_next_track_x != -1:
121
+        snapped_x = snapped_next_track_x
122
+
123
+    return snapped_x
124
+
125
+def return_snapped_x_or_x(snapped_x, x):
126
+    # Return either original or snapped x
127
+    global _snap_happened
128
+    if snapped_x == -1: # indicates no snap happened
129
+        _snap_happened = False
130
+        return x
131
+    else:
132
+        _snap_happened = True
133
+        return snapped_x
134
+        
135
+#---------------------------------------------------- edit mode snapping funcsd
136
+def _overwrite_move_snap(x, track, frame, edit_data):
137
+    if edit_data == None:
138
+        return x
139
+
140
+    snapped_x = -1 # if value stays same till end no snapping happened.
141
+
142
+    press_frame = edit_data["press_frame"]
143
+    first_clip_start = edit_data["first_clip_start"]
144
+    first_clip_frame = first_clip_start + (frame - press_frame)
145
+    first_clip_x = _get_x_for_frame_func(first_clip_frame)
146
+
147
+    snapped_x = -1 # if value stys same till end, no snapping has happened
148
+    snapped_x = _three_track_snap(track, x, first_clip_frame, first_clip_x)
149
+            
150
+    # Return either original x or snapped x
151
+    return return_snapped_x_or_x(snapped_x, x)
152
+
153
+def _object_end_drag_snap(x, track, frame, edit_data):
154
+    if edit_data == None:
155
+        return x
156
+
157
+    frame_x = _get_x_for_frame_func(frame)
158
+
159
+    snapped_x = -1  # if value stays same till end no snapping happened.
160
+    snapped_x = _three_track_snap(track, x, frame, frame_x)
161
+        
162
+    # Return either original or snapped x
163
+    return return_snapped_x_or_x(snapped_x, x)
164
+
165
+def _compositor_move_snap(x, track, frame, edit_data):
166
+    if edit_data == None:
167
+        return x
168
+
169
+    snapped_x = -1 # if value stays same till end no snapping happened.
170
+
171
+    comp_in_frame = edit_data["clip_in"] + (frame - edit_data["press_frame"])
172
+    comp_in_x = _get_x_for_frame_func(comp_in_frame)
173
+
174
+    snapped_x = -1 # if value stys same till end, no snapping has happened
175
+    snapped_x = _three_track_snap(track, x, comp_in_frame, comp_in_x)
176
+
177
+    if snapped_x == -1: # indicates no snap happened
178
+        comp_out_frame = edit_data["clip_in"] + (frame - edit_data["press_frame"]) + edit_data["clip_length"] 
179
+        comp_out_x = _get_x_for_frame_func(comp_out_frame)
180
+        snapped_x = _three_track_snap(track, x, comp_out_frame, comp_out_x)
181
+    
182
+    # Return either original x or snapped x
183
+    return return_snapped_x_or_x(snapped_x, x)
184
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/syncsplitevent.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/syncsplitevent.py Changed
28
 
1
@@ -63,6 +63,17 @@
2
 def split_audio(popup_data):
3
     _do_split_audio_edit(popup_data)
4
 
5
+def split_audio_from_clips_list(clips, track):
6
+    item_id = "not actually used"
7
+    for clip in clips:
8
+        # We're using the existing function to do thid need x for clip frame to use it
9
+        index = track.clips.index(clip)
10
+        frame = track.clip_start(index)
11
+        x = tlinewidgets._get_frame_x(frame)
12
+
13
+        popup_data = (clip, track, item_id, x)
14
+        _do_split_audio_edit(popup_data)
15
+    
16
 def _do_split_audio_edit(popup_data):
17
     # NOTE: THIS HARD CODES ALL SPLITS TO HAPPEN ON TRACK A1, THIS MAY CHANGE
18
     to_track = current_sequence().tracks[current_sequence().first_video_index - 1]
19
@@ -98,7 +109,7 @@
20
         return
21
 
22
     gdk_window = gui.tline_display.get_parent_window();
23
-    gdk_window.set_cursor(Gdk.Cursor.new(Gdk.TCROSS))
24
+    gdk_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.TCROSS))
25
     editorstate.edit_mode = editorstate.SELECT_PARENT_CLIP
26
     global parent_selection_data
27
     parent_selection_data = (clip, child_index, track)
28
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/tlineaction.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tlineaction.py Changed
201
 
1
@@ -30,11 +30,13 @@
2
 from operator import itemgetter
3
 
4
 import appconsts
5
+import compositormodes
6
 import dialogs
7
 import dialogutils
8
 import glassbuttons
9
 import gui
10
 import guicomponents
11
+import guiutils
12
 import edit
13
 import editevent
14
 import editorpersistance
15
@@ -49,6 +51,7 @@
16
 import mlttransitions
17
 import render
18
 import renderconsumer
19
+import respaths
20
 import syncsplitevent
21
 import updater
22
 import utils
23
@@ -414,7 +417,71 @@
24
     updater.display_tline_cut_frame(track, track.get_clip_index_at(mark_in_frame))
25
 
26
 def resync_button_pressed():
27
-    syncsplitevent.resync_selected()
28
+    if movemodes.selected_track != -1:
29
+        syncsplitevent.resync_selected()
30
+    else:
31
+        if compositormodes.compositor != None:
32
+            sync_compositor(compositormodes.compositor)
33
+
34
+def sync_compositor(compositor):
35
+    track = current_sequence().tracks[compositor.transition.b_track] # b_track is source track where origin clip is
36
+    origin_clip = None
37
+    for clip in track.clips:
38
+        if clip.id == compositor.origin_clip_id:
39
+            origin_clip = clip
40
+    if origin_clip == None:
41
+        dialogutils.info_message(_("Origin clip not found!"), 
42
+                             _("Clip used to create this Compositor has been removed\nor moved to different track."), 
43
+                             gui.editor_window.window)
44
+        return
45
+    clip_index = track.clips.index(origin_clip)
46
+    clip_start = track.clip_start(clip_index)
47
+    clip_end = clip_start + origin_clip.clip_out - origin_clip.clip_in
48
+    data = {"compositor":compositor,"clip_in":clip_start,"clip_out":clip_end}
49
+    action = edit.move_compositor_action(data)
50
+    action.do_edit()
51
+    
52
+def split_audio_button_pressed():
53
+    if movemodes.selected_track == -1:
54
+        return
55
+    
56
+    track = current_sequence().tracks[movemodes.selected_track]
57
+    clips = []
58
+    for i in range(movemodes.selected_range_in, movemodes.selected_range_out + 1):
59
+        
60
+        clip = track.clips[i]
61
+        print i, clip
62
+        if clip.is_blanck_clip == False:
63
+            clips.append(clip)
64
+
65
+    syncsplitevent.split_audio_from_clips_list(clips, track)
66
+
67
+def sync_all_compositors():
68
+    # Pair all compositors with their origin clips and clip data
69
+    comp_clip_pairings = {}
70
+    for compositor in current_sequence().compositors:
71
+        comp_clip_pairings[compositor.origin_clip_id] = compositor
72
+    
73
+    for i in range(current_sequence().first_video_index, len(current_sequence().tracks) - 1): # -1, there is a topmost hidden track 
74
+        track = current_sequence().tracks[i] # b_track is source track where origin clip is
75
+        for j in range(0, len(track.clips)):
76
+            clip = track.clips[j]
77
+            if clip.id in comp_clip_pairings:
78
+                compositor = comp_clip_pairings[clip.id]
79
+                comp_clip_pairings[clip.id] = (clip, track, j, compositor)
80
+
81
+    # Do sync
82
+    for origin_clip_id in comp_clip_pairings:
83
+        try:
84
+            clip, track, clip_index, compositor = comp_clip_pairings[origin_clip_id]
85
+            clip_start = track.clip_start(clip_index)
86
+            clip_end = clip_start + clip.clip_out - clip.clip_in
87
+            data = {"compositor":compositor,"clip_in":clip_start,"clip_out":clip_end}
88
+            action = edit.move_compositor_action(data)
89
+            action.do_edit()
90
+        except:
91
+            # Clip is probably  already deleted
92
+            pass
93
 
94
 def add_transition_menu_item_selected():
95
     if movemodes.selected_track == -1:
96
@@ -565,7 +632,8 @@
97
     if _check_transition_handles((from_part - add_thingy),
98
                                  transition_data["from_handle"], 
99
                                  to_part - (1 - add_thingy), 
100
-                                 transition_data["to_handle"]) == False:
101
+                                 transition_data["to_handle"],
102
+                                 length) == False:
103
         return
104
     
105
     # Get from in and out frames
106
@@ -623,25 +691,66 @@
107
     action = edit.add_centered_transition_action(data)
108
     action.do_edit()
109
 
110
-def _check_transition_handles(from_req, from_handle, to_req, to_handle):
111
+def _check_transition_handles(from_req, from_handle, to_req, to_handle, length):
112
 
113
-    if from_req > from_handle:
114
-        info_text = _("There is not enough material available in the FROM clip after the cut") + \
115
-                    _("\nto create the transition.\n\n") + \
116
-                    _("<b>Available:</b> ") + str(from_handle) + _(" frame(s)\n") + \
117
-                    _("<b>Required:</b> ") + str(from_req) + _(" frame(s)")
118
-        dialogutils.info_message(_("FROM Clip Handle is too short!"),
119
-                                 info_text,
120
-                                 gui.editor_window.window)
121
-        return False
122
-    if to_req  > to_handle:
123
-        info_text = _("There is not enough material available in the TO clip before the cut") + \
124
-                    _("\nto create the transition.\n\n") + \
125
-                    _("<b>Available:</b> ") + str(to_handle) + _(" frame(s)\n") + \
126
-                    _("<b>Required:</b> ") + str(to_req) + _(" frame(s)")
127
-        dialogutils.info_message(_("TO Clip Handle is too short!"),
128
-                                 info_text,
129
-                                 gui.editor_window.window)
130
+    if from_req > from_handle or to_req  > to_handle:
131
+        SPACE_TAB = "    "
132
+        info_text = _("To create a rendered transition you need enough media overlap from both clips!\n\n")
133
+        first_clip_info = None
134
+        if from_req > from_handle:
135
+        
136
+            first_clip_info = \
137
+                        _("<b>FIRST CLIP MEDIA OVERLAP:</b>  ") + \
138
+                        SPACE_TAB + _("Available <b>") + str(from_handle) + _("</b> frame(s), " ) + \
139
+                        SPACE_TAB + _("Required <b>") + str(from_req) + _("</b> frame(s)")
140
+
141
+
142
+        second_clip_info = None
143
+        if to_req  > to_handle:
144
+            second_clip_info = \
145
+                            _("<b>SECOND CLIP MEDIA OVERLAP:</b> ") + \
146
+                            SPACE_TAB + _("Available <b>") + str(to_handle) + _("</b> frame(s), ") + \
147
+                            SPACE_TAB + _("Required <b>") + str(to_req) + _("</b> frame(s) ")
148
+
149
+        
150
+        img = Gtk.Image.new_from_file ((respaths.IMAGE_PATH + "transition_wrong.png"))
151
+        img2 = Gtk.Image.new_from_file ((respaths.IMAGE_PATH + "transition_right.png"))
152
+        img2.set_margin_bottom(24)
153
+
154
+        label1 = Gtk.Label(_("Current situation, not enought media overlap:"))
155
+        label1.set_margin_bottom(12)
156
+        label2 = Gtk.Label(_("You need more media overlap:"))
157
+        label2.set_margin_bottom(12)
158
+        label2.set_margin_top(24)
159
+        label3 = Gtk.Label(info_text)
160
+        label3.set_use_markup(True)
161
+        if first_clip_info != None:
162
+            label4 = Gtk.Label(first_clip_info)
163
+            label4.set_use_markup(True)
164
+        if second_clip_info != None:
165
+            label5 = Gtk.Label(second_clip_info)
166
+            label5.set_use_markup(True)
167
+        
168
+        row1 = guiutils.get_centered_box([label1])
169
+        row2 = guiutils.get_centered_box([img])
170
+        row3 = guiutils.get_centered_box([label2])
171
+        row4 = guiutils.get_centered_box([img2])
172
+        row5 = guiutils.get_centered_box([label3])
173
+        
174
+        rows = [row1, row2, row3, row4]
175
+
176
+        
177
+        if first_clip_info != None:
178
+            row6 = guiutils.get_left_justified_box([label4])
179
+            rows.append(row6)
180
+        if second_clip_info != None:
181
+            row7 = guiutils.get_left_justified_box([label5])
182
+            rows.append(row7)
183
+        
184
+
185
+        dialogutils.warning_message_with_panels(_("More media overlap needed to create transition!"), 
186
+                                                "", gui.editor_window.window, True, dialogutils.dialog_destroy, rows)
187
+                
188
         return False
189
 
190
     return True
191
@@ -752,9 +861,14 @@
192
     guicomponents.get_monitor_view_popupmenu(launcher, event, _view_mode_menu_item_item_activated)
193
     
194
 def _view_mode_menu_item_item_activated(widget, msg):
195
-    editorstate.current_sequence().set_output_mode(msg)
196
-    gui.editor_window.view_mode_select.set_pixbuf(msg)
197
-
198
+    if msg < 3:
199
+        editorstate.current_sequence().set_output_mode(msg)
200
+        gui.editor_window.view_mode_select.set_pixbuf(msg)
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/tlinewidgets.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tlinewidgets.py Changed
201
 
1
@@ -39,12 +39,14 @@
2
 from editorstate import current_sequence
3
 from editorstate import timeline_visible
4
 from editorstate import PLAYER
5
+from editorstate import PROJECT
6
 from editorstate import EDIT_MODE
7
 from editorstate import current_proxy_media_paths
8
 import editorstate
9
 import gui
10
 import respaths
11
 import sequence
12
+import snapping
13
 import trimmodes
14
 import utils
15
 import updater
16
@@ -121,6 +123,8 @@
17
 ALL_MUTE_ICON = None
18
 MARKER_ICON = None
19
 LEVELS_RENDER_ICON = None
20
+SNAP_ICON = None
21
+KEYBOARD_ICON = None
22
 
23
 # tc scale
24
 TC_POINTER_HEAD = None
25
@@ -200,6 +204,7 @@
26
 SYNC_GONE_COLOR = (0.4, 0.4, 0.4)
27
 
28
 PROXY_STRIP_COLOR = (0.40, 0.60, 0.82)
29
+PROXY_STRIP_COLOR_SELECTED = (0.52, 0.72, 0.96)
30
 
31
 MARK_COLOR = (0.1, 0.1, 0.1)
32
 
33
@@ -212,6 +217,8 @@
34
 DARK_FRAME_SCALE_SELECTED_COLOR_GRAD = get_multiplied_grad(0, 1, FRAME_SCALE_COLOR_GRAD, 0.7)
35
 DARK_FRAME_SCALE_SELECTED_COLOR_GRAD_L = get_multiplied_grad(1, 1, FRAME_SCALE_SELECTED_COLOR_GRAD, GRAD_MULTIPLIER * 0.8) 
36
 
37
+ICON_SELECTED_OVERLAY_COLOR = (0.8, 0.8, 1.0, 0.3)
38
+
39
 FRAME_SCALE_LINES = (0, 0, 0)
40
 
41
 BG_COLOR = (0.5, 0.5, 0.55)#(0.6, 0.6, 0.65)
42
@@ -267,12 +274,16 @@
43
 # Used to draw indicators that tell if more frames are available while trimming
44
 trim_status = appconsts.ON_BETWEEN_FRAME
45
 
46
+# Dict for clip thumbnails path -> image
47
+clip_thumbnails = {}
48
+
49
 # ------------------------------------------------------------------- module functions
50
 def load_icons():
51
     global FULL_LOCK_ICON, FILTER_CLIP_ICON, VIEW_SIDE_ICON,\
52
     COMPOSITOR_CLIP_ICON, INSERT_ARROW_ICON, AUDIO_MUTE_ICON, MARKER_ICON, \
53
     VIDEO_MUTE_ICON, ALL_MUTE_ICON, TRACK_BG_ICON, MUTE_AUDIO_ICON, MUTE_VIDEO_ICON, MUTE_ALL_ICON, \
54
-    TRACK_ALL_ON_V_ICON, TRACK_ALL_ON_A_ICON, MUTE_AUDIO_A_ICON, TC_POINTER_HEAD, EDIT_INDICATOR, LEVELS_RENDER_ICON
55
+    TRACK_ALL_ON_V_ICON, TRACK_ALL_ON_A_ICON, MUTE_AUDIO_A_ICON, TC_POINTER_HEAD, EDIT_INDICATOR, \
56
+    LEVELS_RENDER_ICON, SNAP_ICON, KEYBOARD_ICON
57
 
58
     FULL_LOCK_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "full_lock.png")
59
     FILTER_CLIP_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "filter_clip_icon_sharp.png")
60
@@ -287,6 +298,8 @@
61
     MUTE_VIDEO_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "track_video_mute.png")
62
     MUTE_ALL_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "track_all_mute.png")
63
     LEVELS_RENDER_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "audio_levels_render.png")
64
+    SNAP_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "snap_magnet.png")
65
+    KEYBOARD_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "keyb_trim.png")
66
 
67
     MARKER_ICON = _load_pixbuf("marker.png")
68
     TRACK_ALL_ON_V_ICON = _load_pixbuf("track_all_on_V.png")
69
@@ -489,7 +502,9 @@
70
 
71
     arrow_x = start_x + ((end_x - start_x)/2.0)
72
     _draw_mode_arrow(cr, arrow_x, y, OVERWRITE_MODE_COLOR)
73
-
74
+    
75
+    _draw_snap(cr, y)
76
+     
77
 def _draw_move_overlay(cr, data, y):
78
     # Get data
79
     press_frame = data["press_frame"]
80
@@ -645,6 +660,8 @@
81
     cr.line_to(selection_frame_x - radius - bit, track_y + track_height)
82
     cr.stroke()
83
 
84
+    _draw_kb_trim_indicator(cr, selection_frame_x, track_y)
85
+    
86
 def draw_one_roll_overlay(cr, data):
87
     track_height = current_sequence().tracks[data["track"]].height
88
     track_y = _get_track_y(data["track"])
89
@@ -704,6 +721,8 @@
90
         cr.line_to(selection_frame_x - radius - bit, track_y + track_height)
91
     cr.stroke()
92
 
93
+    _draw_kb_trim_indicator(cr, selection_frame_x, track_y)
94
+    
95
 def draw_slide_overlay(cr, data):
96
     track_height = current_sequence().tracks[data["track"]].height
97
     track_y = _get_track_y(data["track"])
98
@@ -764,6 +783,8 @@
99
     cr.set_source_surface(VIEW_SIDE_ICON, x, track_y + 4)
100
     cr.paint()
101
 
102
+    _draw_kb_trim_indicator(cr, x, track_y)
103
+    
104
 def draw_clip_end_drag_overlay(cr, data):
105
     if data["editing_clip_end"] == True:
106
         end = data["frame"]  - pos
107
@@ -786,6 +807,8 @@
108
     cr.rectangle(scale_in, int(y) + 1.5, int(scale_length), track_height - 2.0)
109
     cr.stroke()
110
 
111
+    _draw_snap(cr, y)
112
+    
113
 def draw_compositor_move_overlay(cr, data):
114
     # Get data
115
     press_frame = data["press_frame"]
116
@@ -808,7 +831,9 @@
117
     cr.set_line_width(2.0)
118
     cr.set_source_rgb(*OVERLAY_COLOR)
119
     cr.stroke()
120
-    
121
+
122
+    _draw_snap(cr, y)
123
+
124
 def draw_compositor_trim(cr, data):
125
     clip_in = data["clip_in"]
126
     clip_out = data["clip_out"]
127
@@ -835,6 +860,8 @@
128
         x = scale_in + scale_length - 26
129
     _draw_two_arrows(cr, x, y + 4, 4)
130
 
131
+    _draw_snap(cr, y)
132
+    
133
 def _create_compositor_cairo_path(cr, scale_in, scale_length, y, target_y):
134
     scale_in = int(scale_in) + 0.5
135
     scale_length = int(scale_length)
136
@@ -921,6 +948,17 @@
137
     cr.set_source_surface(VIEW_SIDE_ICON, x, y)
138
     cr.paint()
139
 
140
+def _draw_snap(cr, y):
141
+    if snapping.snap_active() == True and snapping.show_magnet_icon == True:
142
+        cr.set_source_surface(SNAP_ICON, int(snapping.get_snap_x()) - 6, int(y) - 14)
143
+        cr.paint()
144
+
145
+def _draw_kb_trim_indicator(cr, x, y):
146
+    if trimmodes.submode == trimmodes.KEYB_EDIT_ON:
147
+        cr.set_source_surface(KEYBOARD_ICON, int(x) - 9, int(y) - 16)
148
+        cr.paint()
149
+
150
+
151
 # ------------------------------- WIDGETS
152
 class TimeLineCanvas:
153
     """
154
@@ -983,6 +1021,10 @@
155
             button = 1
156
         elif (state & Gdk.ModifierType.BUTTON3_MASK):
157
             button = 3
158
+        
159
+        track = get_track(y)
160
+        x = snapping.get_snapped_x(x, track, self.edit_mode_data)
161
+            
162
         self.move_listener(x, y, get_frame(x), button, state)
163
         
164
     def _release_event(self, event):
165
@@ -990,7 +1032,12 @@
166
         Mouse release callback.
167
         """
168
         self.drag_on = False
169
-        self.release_listener(event.x, event.y, get_frame(event.x), \
170
+        
171
+        track = get_track(event.y)
172
+        x = snapping.get_snapped_x(event.x, track, self.edit_mode_data)
173
+        snapping.mouse_edit_ended()
174
+        
175
+        self.release_listener(x, event.y, get_frame(x), \
176
                               event.button, event.get_state())
177
 
178
     def set_pointer_context(self, x, y):
179
@@ -1072,7 +1119,7 @@
180
         if self.edit_mode_overlay_draw_func != None:
181
             self.edit_mode_overlay_draw_func(cr,self.edit_mode_data)
182
         
183
-        audiowaveformrenderer.render_queued()
184
+        audiowaveformrenderer.launch_queued_renders()
185
 
186
     def draw_track(self, cr, track, y, width):
187
         """
188
@@ -1112,6 +1159,8 @@
189
 
190
         proxy_paths = current_proxy_media_paths()
191
 
192
+        global clip_thumbnails
193
+                
194
         # Draw clips in draw range
195
         for i in range(start, end):
196
 
197
@@ -1167,7 +1216,7 @@
198
                         else:
199
                             cr.set_source_rgb(*IMAGE_CLIP_SELECTED_COLOR)
200
                             clip_bg_col = IMAGE_CLIP_SELECTED_COLOR
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/tools/batchrendering.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/batchrendering.py Changed
68
 
1
@@ -116,8 +116,9 @@
2
             project = persistance.load_project(project_file_path, False)
3
 
4
             producer = project.c_seq.tractor
5
+            profile = mltprofiles.get_profile(render_item.render_data.profile_name)
6
             consumer = renderconsumer.get_mlt_render_consumer(render_item.render_path, 
7
-                                                              project.profile,
8
+                                                              profile,
9
                                                               render_item.args_vals_list)
10
 
11
             # Get render range
12
@@ -330,6 +331,10 @@
13
     Gdk.threads_init()
14
     Gdk.threads_enter()
15
 
16
+    # Request dark them if so desired
17
+    if editorpersistance.prefs.dark_theme == True:
18
+        Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", True)
19
+
20
     repo = mlt.Factory().init()
21
 
22
     # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs 
23
@@ -1102,6 +1107,10 @@
24
     Gdk.threads_init()
25
     Gdk.threads_enter()
26
 
27
+    # Request dark them if so desired
28
+    if editorpersistance.prefs.dark_theme == True:
29
+        Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", True)
30
+
31
     repo = mlt.Factory().init()
32
 
33
     # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs 
34
@@ -1157,8 +1166,9 @@
35
         project = persistance.load_project(project_file_path, False)
36
 
37
         producer = project.c_seq.tractor
38
+        profile = mltprofiles.get_profile(render_item.render_data.profile_name)
39
         consumer = renderconsumer.get_mlt_render_consumer(render_item.render_path, 
40
-                                                          project.profile,
41
+                                                          profile,
42
                                                           render_item.args_vals_list)
43
 
44
         # Get render range
45
@@ -1242,11 +1252,11 @@
46
                                    lambda w, e: _start_single_render_shutdown(), 
47
                                    None)
48
 
49
-        self.not_rendering_txt = "0 %"
50
         self.render_progress_bar = Gtk.ProgressBar()
51
-        self.render_progress_bar.set_text(self.not_rendering_txt)
52
+        self.progress_label = Gtk.Label("0 %")
53
         
54
         button_row =  Gtk.HBox(False, 0)
55
+        button_row.pack_start(self.progress_label, False, False, 0)
56
         button_row.pack_start(Gtk.Label(), True, True, 0)
57
         button_row.pack_start(self.stop_render_button, False, False, 0)
58
 
59
@@ -1270,7 +1280,7 @@
60
         self.render_progress_bar.set_fraction(fraction)
61
 
62
         progress_str = str(int(fraction * 100)) + " %"
63
-        self.render_progress_bar.set_text(progress_str)
64
+        self.progress_label.set_text(progress_str)
65
 
66
         if fraction != 0:
67
             full_time_est = (1.0 / fraction) * current_render_time_passed
68
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/gmic.py Added
201
 
1
@@ -0,0 +1,1282 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor. If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+from gi.repository import GObject, GLib
23
+from gi.repository import Gtk, Gdk, GdkPixbuf
24
+from gi.repository import GdkX11
25
+from gi.repository import Pango
26
+
27
+import cairo
28
+import locale
29
+import mlt
30
+import numpy as np
31
+import os
32
+import re
33
+import shutil
34
+import subprocess
35
+import sys
36
+import time
37
+import webbrowser
38
+
39
+import appconsts
40
+import cairoarea
41
+import dialogutils
42
+import editorstate
43
+import editorpersistance
44
+import gui
45
+import guicomponents
46
+import guiutils
47
+import glassbuttons
48
+import mltenv
49
+import mltprofiles
50
+import mlttransitions
51
+import mltfilters
52
+import positionbar
53
+import render
54
+import respaths
55
+import renderconsumer
56
+import toolguicomponents
57
+import toolsencoding
58
+import translations
59
+import threading
60
+import utils
61
+
62
+import gmicplayer
63
+import gmicscript
64
+
65
+MONITOR_WIDTH = 500
66
+MONITOR_HEIGHT = 300 # initial value, this gets changed when material is loaded
67
+CLIP_FRAMES_DIR = "/clip_frames"
68
+RENDER_FRAMES_DIR = "/render_frames"
69
+PREVIEW_FILE = "preview.png"
70
+NO_PREVIEW_FILE = "fallback_thumb.png"
71
+
72
+_gmic_found = False
73
+
74
+_session_id = None
75
+
76
+_window = None
77
+
78
+_player = None
79
+_preview_render = None
80
+_frame_writer = None
81
+_effect_renderer = None
82
+
83
+_current_path = None
84
+_current_preview_surface = None
85
+_current_dimensions = None
86
+_current_fps = None
87
+_current_profile_index = None
88
+_render_data = None
89
+_last_load_file = None
90
+    
91
+_encoding_panel = None
92
+
93
+# GTK3 requires this to be created outside of callback
94
+_hamburger_menu = Gtk.Menu()
95
+
96
+#-------------------------------------------------- launch and inits
97
+def test_availablity():
98
+    if os.path.exists("/usr/bin/gmic") == True:
99
+        print "G'MIC found"
100
+        global _gmic_found
101
+        _gmic_found = True
102
+    else:
103
+        print "G'MIC NOT found"
104
+        
105
+def launch_gmic():
106
+    if _gmic_found == False:
107
+        primary_txt = _("G'Mic not found!")
108
+        secondary_txt = _("G'Mic binary was not present at <b>/usr/bin/gmic</b>.\nInstall G'MIC to use this tool.")
109
+        dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
110
+        return
111
+
112
+    print "Launch gmic..."
113
+    gui.save_current_colors()
114
+    
115
+    FLOG = open(utils.get_hidden_user_dir_path() + "log_gmic", 'w')
116
+    subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladegmic"], stdin=FLOG, stdout=FLOG, stderr=FLOG)
117
+
118
+
119
+def main(root_path, force_launch=False):
120
+       
121
+    gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version())
122
+    editorstate.gtk_version = gtk_version
123
+    try:
124
+        editorstate.mlt_version = mlt.LIBMLT_VERSION
125
+    except:
126
+        editorstate.mlt_version = "0.0.99" # magic string for "not found"
127
+
128
+    global _session_id
129
+    _session_id = int(time.time() * 1000) # good enough
130
+
131
+    # Set paths.
132
+    respaths.set_paths(root_path)
133
+
134
+    # Init gmic tool session dirs
135
+    if os.path.exists(get_session_folder()):
136
+        shutil.rmtree(get_session_folder())
137
+        
138
+    os.mkdir(get_session_folder())
139
+    
140
+    init_frames_dirs()
141
+    
142
+    # Load editor prefs and list of recent projects
143
+    editorpersistance.load()
144
+    if editorpersistance.prefs.dark_theme == True:
145
+        respaths.apply_dark_theme()
146
+
147
+    # Init translations module with translations data
148
+    translations.init_languages()
149
+    translations.load_filters_translations()
150
+    mlttransitions.init_module()
151
+
152
+    # Load preset gmic scripts
153
+    gmicscript.load_preset_scripts_xml()
154
+    
155
+    # Init gtk threads
156
+    Gdk.threads_init()
157
+    Gdk.threads_enter()
158
+
159
+    # Request dark them if so desired
160
+    if editorpersistance.prefs.dark_theme == True:
161
+        Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", True)
162
+
163
+    repo = mlt.Factory().init()
164
+
165
+    # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs 
166
+    locale.setlocale(locale.LC_NUMERIC, 'C')
167
+
168
+    # Check for codecs and formats on the system
169
+    mltenv.check_available_features(repo)
170
+    renderconsumer.load_render_profiles()
171
+
172
+    # Load filter and compositor descriptions from xml files.
173
+    mltfilters.load_filters_xml(mltenv.services)
174
+    mlttransitions.load_compositors_xml(mltenv.transitions)
175
+
176
+    # Create list of available mlt profiles
177
+    mltprofiles.load_profile_list()
178
+
179
+    gui.load_current_colors()
180
+    
181
+    global _window
182
+    _window = GmicWindow()
183
+    _window.pos_bar.set_dark_bg_color()
184
+
185
+    os.putenv('SDL_WINDOWID', str(_window.monitor.get_window().get_xid()))
186
+    Gdk.flush()
187
+        
188
+    Gtk.main()
189
+    Gdk.threads_leave()
190
+
191
+def init_frames_dirs():
192
+    os.mkdir(get_clip_frames_dir())
193
+    os.mkdir(get_render_frames_dir())
194
+
195
+#----------------------------------------------- session folders and files
196
+def get_session_folder():
197
+    return utils.get_hidden_user_dir_path() + appconsts.GMIC_DIR + "/session_" + str(_session_id)
198
+
199
+def get_clip_frames_dir():
200
+    return get_session_folder() + CLIP_FRAMES_DIR
201
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/gmicplayer.py Added
198
 
1
@@ -0,0 +1,196 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+"""
23
+Clip player used to select frames for preview and range selection.
24
+"""
25
+
26
+from gi.repository import Gdk
27
+
28
+import mlt
29
+import os
30
+import time
31
+
32
+import mltprofiles
33
+import utils
34
+
35
+TICKER_DELAY = 0.25
36
+RENDER_TICKER_DELAY = 0.05
37
+
38
+_current_profile = None
39
+
40
+def set_current_profile(clip_path):
41
+    profile = mltprofiles.get_default_profile()
42
+    producer = mlt.Producer(profile, str(clip_path))
43
+    global _current_profile
44
+    profile_index = mltprofiles.get_closest_matching_profile_index(utils.get_file_producer_info(producer))
45
+    _current_profile = mltprofiles.get_profile_for_index(profile_index)
46
+    return profile_index
47
+
48
+class GmicPlayer:
49
+    
50
+    def __init__(self, clip_path):
51
+        self.producer = mlt.Producer(_current_profile, str(clip_path))
52
+        self.producer.mark_in = -1
53
+        self.producer.mark_out = -1
54
+        
55
+    def create_sdl_consumer(self):
56
+        """
57
+        Creates consumer with sdl output to a gtk+ widget.
58
+        """
59
+        # Create consumer and set params
60
+        self.consumer = mlt.Consumer(_current_profile, "sdl")
61
+        self.consumer.set("real_time", 1)
62
+        self.consumer.set("rescale", "bicubic") # MLT options "nearest", "bilinear", "bicubic", "hyper"
63
+        self.consumer.set("resize", 1)
64
+        self.consumer.set("progressive", 1)
65
+
66
+        # Hold ref to switch back from rendering
67
+        self.sdl_consumer = self.consumer 
68
+
69
+    def refresh(self): # Window events need this to get picture back
70
+        self.consumer.stop()
71
+        self.consumer.start()
72
+
73
+    def connect_and_start(self):
74
+        """
75
+        Connects current procer and consumer and
76
+        """
77
+        self.consumer.purge()
78
+        self.producer.set_speed(0)
79
+        self.consumer.connect(self.producer)
80
+        self.consumer.start()
81
+
82
+    def current_frame(self):
83
+        return self.producer.frame()
84
+
85
+    def get_active_length(self):
86
+        return self.producer.get_length()
87
+                
88
+    def seek_position_normalized(self, pos, length):
89
+        frame_number = pos * length
90
+        self.seek_frame(int(frame_number)) 
91
+    
92
+    def seek_frame(self, frame):
93
+        # Force range
94
+        length = self.get_active_length()
95
+        if frame < 0:
96
+            frame = 0
97
+        elif frame >= length:
98
+            frame = length - 1
99
+
100
+        #self.producer.set_speed(0)
101
+        self.producer.seek(frame) 
102
+    
103
+    def seek_delta(self, delta):
104
+        # Get new frame
105
+        frame = self.producer.frame() + delta
106
+        # Seek frame
107
+        self.seek_frame(frame)
108
+        
109
+    def get_rgb_frame(self):
110
+        frame = self.producer.get_frame()
111
+        # And make sure we deinterlace if input is interlaced
112
+        frame.set("consumer_deinterlace", 1)
113
+
114
+        # Now we are ready to get the image and save it.
115
+        size = (self.profile.width(), self.profile.height())
116
+        rgb = frame.get_image(mlt.mlt_image_rgb24a, *size) 
117
+        return rgb
118
+
119
+    def shutdown(self):
120
+        self.producer.set_speed(0)
121
+        self.consumer.stop()
122
+
123
+
124
+class PreviewFrameWriter:
125
+
126
+    def __init__(self, file_path):
127
+        self.producer = mlt.Producer(_current_profile, str(file_path))
128
+            
129
+    def write_frame(self, clip_folder, frame):
130
+        """
131
+        Writes thumbnail image from file producer
132
+        """
133
+        # Get data
134
+        
135
+        frame_path = clip_folder + "frame" + str(frame) +  ".png"
136
+
137
+        # Create consumer
138
+        consumer = mlt.Consumer(_current_profile, "avformat", frame_path)
139
+        consumer.set("real_time", 0)
140
+        consumer.set("vcodec", "png")
141
+
142
+        frame_producer = self.producer.cut(frame, frame)
143
+
144
+        # Connect and write image
145
+        consumer.connect(frame_producer)
146
+        consumer.run()
147
+        
148
+        
149
+class FramesRangeWriter:
150
+
151
+    def __init__(self, file_path, callback):
152
+        self.producer = mlt.Producer(_current_profile, str(file_path))
153
+        self.callback = callback
154
+        self.running = True
155
+
156
+    def write_frames(self, clip_folder, frame_name, mark_in, mark_out):
157
+        """
158
+        Writes thumbnail image from file producer
159
+        """
160
+        # Get data
161
+        render_path = clip_folder + frame_name + "_%04d." + "png"
162
+
163
+        self.consumer = mlt.Consumer(_current_profile, "avformat", str(render_path))
164
+        self.consumer.set("real_time", -1)
165
+        self.consumer.set("rescale", "bicubic")
166
+        self.consumer.set("vcodec", "png")
167
+    
168
+        self.frame_producer = self.producer.cut(mark_in, mark_out)
169
+
170
+        self.consumer.connect(self.frame_producer)
171
+        self.frame_producer.set_speed(0)
172
+        self.frame_producer.seek(0)
173
+        self.frame_producer.set_speed(1)
174
+        self.consumer.start()
175
+
176
+        print "Rendering frames range"
177
+                
178
+        while self.running: # set false at shutdown() for abort
179
+            if self.frame_producer.frame() >= mark_out:
180
+                
181
+                self.callback(self.frame_producer.frame() - mark_in)
182
+                time.sleep(2.0) # This seems enough, other methods produced bad waits
183
+
184
+                self.running = False
185
+            else:
186
+                self.callback(self.frame_producer.frame())
187
+                time.sleep(0.2)
188
+    
189
+    def shutdown(self):
190
+        if self.running == False:
191
+            return
192
+
193
+        self.consumer.stop()
194
+        self.frame_producer.set_speed(0)
195
+        self.running = False
196
+        
197
+        
198
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/gmicscript.py Added
139
 
1
@@ -0,0 +1,137 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor. If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+
23
+from gi.repository import Gtk
24
+import xml.dom.minidom
25
+
26
+import respaths
27
+
28
+GMIC_SCRIPT_NODE = "gmicscript"
29
+
30
+_scripts = None
31
+_script_groups = []
32
+_scripts_menu = Gtk.Menu()
33
+
34
+class GmicScript:
35
+    """
36
+    Info of a filter (mlt.Service) that is is available to the user.
37
+    Constructor input is a dom node object.
38
+    This is used to create FilterObject objects.
39
+    """
40
+    def __init__(self, script_node):
41
+        self.name = script_node.getElementsByTagName("name").item(0).firstChild.nodeValue
42
+        self.script = script_node.getElementsByTagName("script").item(0).firstChild.nodeValue
43
+        self.group = script_node.getElementsByTagName("group").item(0).firstChild.nodeValue
44
+
45
+def get_scripts():
46
+    return _scripts
47
+
48
+def load_preset_scripts_xml():
49
+
50
+    _script_groups_names = {}
51
+    _script_groups_names["Black and White"] = _("Black and White")
52
+    _script_groups_names["Filter"] = _("Filter")
53
+    _script_groups_names["Blur"] = _("Blur")
54
+    _script_groups_names["Special Effect"] = _("Special Effect")
55
+    _script_groups_names["Misc"] = _("Misc")
56
+    _script_groups_names["Drawing"] = _("Drawing")
57
+    _script_groups_names["Painting"] = _("Painting")
58
+    _script_groups_names["Transform"] = _("Transform")
59
+    _script_groups_names["Glow"] = _("Glow")
60
+    _script_groups_names["Geometric"] = _("Geometric")
61
+    _script_groups_names["Edges"] = _("Edges")
62
+    _script_groups_names["New"] = _("New")
63
+    _script_groups_names["Texture"] = _("Texture")
64
+    _script_groups_names["Technical"] = _("Technical")
65
+    _script_groups_names["Photographic"] = _("Photographic")
66
+    _script_groups_names["Pattern"] = _("Pattern")
67
+    _script_groups_names["Artistic"] = _("Artistic")
68
+    _script_groups_names["Basic"] = _("Basic")
69
+    _script_groups_names["Film Emulate Print"] = _("Film Emulate Print")
70
+    _script_groups_names["Film Emulate Negative Color"] = _("Film Emulate Negative Color")
71
+    _script_groups_names["Film Emulate Negative New"] = _("Film Emulate Negative New")
72
+    _script_groups_names["Film Emulate Add Grain"] = _("Film Emulate Add Grain")
73
+    _script_groups_names["Film Emulate BW"] = _("Film Emulate BW")
74
+    _script_groups_names["Film Emulate Negative Old"] = _("Film Emulate Negative Old")
75
+    _script_groups_names["Film Emulate Instant Consumer"] = _("Film Emulate Instant Consumer")
76
+    _script_groups_names["Film Emulate Instant Pro"] = _("Film Emulate Instant Pro")
77
+    _script_groups_names["Film Emulate Slide"] = _("Film Emulate Slide")
78
+    _script_groups_names["Film Emulate FX"] = _("Film Emulate FX")
79
+
80
+    presets_doc = xml.dom.minidom.parse(respaths.GMIC_SCRIPTS_DOC)
81
+
82
+    global _scripts
83
+    _scripts = []
84
+    load_groups = {}
85
+    script_nodes = presets_doc.getElementsByTagName(GMIC_SCRIPT_NODE)
86
+    for script_node in script_nodes:
87
+        gmic_script = GmicScript(script_node)
88
+        _scripts.append(gmic_script)
89
+
90
+        # Add filter compositor filters or filter groups
91
+        try:
92
+            translated_group_name = _script_groups_names[gmic_script.group]
93
+        except:
94
+            translated_group_name = "Misc"
95
+
96
+        try:
97
+            group = load_groups[translated_group_name]
98
+            group.append(gmic_script)
99
+        except:
100
+            load_groups[translated_group_name] = [gmic_script]
101
+
102
+    # We used translated group names as keys in load_groups
103
+    # Now we sort them and use them to place data in groups array in the same
104
+    # order as it will be presented to user, so selection indexes in gui components will match
105
+    # group array indexes here.
106
+    sorted_keys = sorted(load_groups.keys())
107
+    global _script_groups
108
+    for gkey in sorted_keys:
109
+        group = load_groups[gkey]
110
+        add_group = sorted(group, key=lambda gmic_script: gmic_script.name)
111
+        _script_groups.append((gkey, add_group))
112
+
113
+def get_default_script():
114
+    key, group = _script_groups[0]
115
+    return group[0]
116
+
117
+def show_menu(event, callback):
118
+    # Remove current items
119
+    items = _scripts_menu.get_children()
120
+    for item in items:
121
+        _scripts_menu.remove(item)
122
+
123
+    for script_group in _script_groups:
124
+        group_name, group = script_group
125
+        group_item = Gtk.MenuItem(group_name)
126
+        #group_item.connect("activate", callback, i)
127
+        _scripts_menu.append(group_item)
128
+        sub_menu = Gtk.Menu()
129
+        group_item.set_submenu(sub_menu)
130
+
131
+        for script in group:
132
+            script_item = Gtk.MenuItem(script.name)
133
+            sub_menu.append(script_item)
134
+            script_item.connect("activate", callback, script)
135
+
136
+    _scripts_menu.show_all()
137
+    _scripts_menu.popup(None, None, None, None, event.button, event.time)
138
+
139
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/phantomcompositor.py Added
76
 
1
@@ -0,0 +1,74 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+import os
22
+import subprocess
23
+import sys
24
+
25
+from gi.repository import Gtk
26
+
27
+import dialogutils
28
+import editorstate
29
+import guiutils
30
+import gui
31
+import respaths
32
+import utils
33
+
34
+_phantom_found = False
35
+
36
+def test_availablity():
37
+    global _phantom_found
38
+    if os.path.exists(respaths.PHANTOM_JAR) == True:
39
+        _phantom_found = True
40
+
41
+def launch_phantom():
42
+    respaths.PHANTOM_JAR
43
+    if _phantom_found == False:
44
+        info_row = guiutils.get_centered_box([Gtk.Label(_("Phantom2D tool has not been installed on your system."))])
45
+        
46
+        link_info_row = guiutils.get_centered_box([Gtk.Label(_("Install instructions:"))])
47
+        link = Gtk.LinkButton.new("https://github.com/jliljebl/phantom2D")
48
+        link_row = guiutils.get_centered_box([link])
49
+
50
+        dir_info_row = guiutils.get_centered_box([Gtk.Label(_("Install directory for Phantom2D tool:"))])
51
+        dir_label = Gtk.Label(respaths.PHANTOM_JAR.rstrip("/Phantom2D.jar"))
52
+        dir_label.set_selectable(True)
53
+        dir_row = guiutils.get_centered_box([Gtk.Label(respaths.PHANTOM_JAR.rstrip("/Phantom2D.jar"))])
54
+        dir_row.set_margin_top(8)
55
+        
56
+        panel = Gtk.VBox()
57
+        panel.pack_start(info_row, False, False, 0)
58
+        panel.pack_start(guiutils.pad_label(12, 24), False, False, 0)
59
+        panel.pack_start(link_info_row, False, False, 0)
60
+        panel.pack_start(link_row, False, False, 0)
61
+        panel.pack_start(guiutils.pad_label(12, 24), False, False, 0)
62
+        panel.pack_start(dir_info_row, False, False, 0)
63
+        panel.pack_start(dir_row, False, False, 0)
64
+        dialogutils.panel_ok_dialog(_("Phantom2D not found"), panel)
65
+        return
66
+
67
+    FLOG = open(utils.get_hidden_user_dir_path() + "log_phantom", 'w')
68
+    subprocess.Popen([str(respaths.LAUNCH_DIR + "flowbladephantom") + " " + str(respaths.PHANTOM_JAR) \
69
+                        + " profile" + " " + _get_underscored_profile() \
70
+                        + " cachefolder "  + utils.get_phantom_disk_cache_folder()], shell=True, stdin=FLOG, stdout=FLOG, stderr=FLOG)
71
+
72
+    print "Phantom2D launched"
73
+
74
+def _get_underscored_profile():
75
+    return editorstate.PROJECT().profile_desc.replace (" ", "_")
76
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/tools/titler.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/titler.py Changed
56
 
1
@@ -48,6 +48,7 @@
2
 
3
 _titler = None
4
 _titler_data = None
5
+_titler_lastdir = None
6
 
7
 _keep_titler_data = True
8
 _open_saved_in_bin = True
9
@@ -105,7 +106,10 @@
10
     if not _keep_titler_data:
11
         _titler_data = None
12
 
13
-
14
+def reset_titler():
15
+    global _titler_data
16
+    _titler_data = None
17
+        
18
 # ------------------------------------------------------------- data
19
 class TextLayer:
20
     """
21
@@ -234,7 +238,6 @@
22
         self.pos_bar.update_display_from_producer(PLAYER().producer)
23
         self.pos_bar.mouse_release_listener = self.pos_bar_mouse_released
24
 
25
-
26
         pos_bar_frame = Gtk.Frame()
27
         pos_bar_frame.add(self.pos_bar.widget)
28
         pos_bar_frame.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
29
@@ -499,7 +502,7 @@
30
         self.show_current_frame()
31
 
32
     def _save_title_pressed(self):
33
-        toolsdialogs.save_titler_graphic_as_dialog(self._save_title_dialog_callback, "title.png", None)
34
+        toolsdialogs.save_titler_graphic_as_dialog(self._save_title_dialog_callback, "title.png", _titler_lastdir)
35
 
36
     def _save_title_dialog_callback(self, dialog, response_id):
37
         if response_id == Gtk.ResponseType.ACCEPT:
38
@@ -508,6 +511,9 @@
39
                 dialog.destroy()
40
                 save_path = filenames[0]
41
                 self.view_editor.write_layers_to_png(save_path)
42
+                (dirname, filename) = os.path.split(save_path)
43
+                global _titler_lastdir
44
+                _titler_lastdir = dirname
45
         
46
                 if _open_saved_in_bin:
47
                     open_file_thread = OpenFileThread(save_path, self.view_editor)
48
@@ -975,6 +981,7 @@
49
         self.scroll.queue_draw()
50
         _filling_layer_list = False
51
 
52
+
53
 class OpenFileThread(threading.Thread):
54
     
55
     def __init__(self, filename, view_editor):
56
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/toolguicomponents.py Added
53
 
1
@@ -0,0 +1,51 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor. If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+import cairoarea
23
+import editorpersistance
24
+
25
+class PressLaunch:
26
+    def __init__(self, callback, w=22, h=22):
27
+        self.widget = cairoarea.CairoDrawableArea2( w, 
28
+                                                    h, 
29
+                                                    self._draw)
30
+        self.widget.press_func = self._press_event
31
+        self.callback = callback
32
+        self.sensitive = True
33
+
34
+    def set_sensitive(self, value):
35
+        self.sensitive = value
36
+        
37
+    def _draw(self, event, cr, allocation):      
38
+        cr.move_to(7, 13)
39
+        cr.line_to(12, 18)
40
+        cr.line_to(17, 13)
41
+        cr.close_path()
42
+        if editorpersistance.prefs.dark_theme == False:
43
+            cr.set_source_rgb(0, 0, 0)
44
+        else:
45
+            cr.set_source_rgb(0.66, 0.66, 0.66)
46
+        cr.fill()
47
+        
48
+    def _press_event(self, event):
49
+        if self.sensitive == False:
50
+           return 
51
+
52
+        self.callback(self.widget, event)
53
flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/tools/toolsencoding.py Added
201
 
1
@@ -0,0 +1,415 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+from gi.repository import Gtk
23
+from gi.repository import GObject
24
+
25
+import os
26
+
27
+import guiutils
28
+import mltprofiles
29
+import renderconsumer
30
+import utils
31
+
32
+widgets = None
33
+disable_audio_encoding = False
34
+default_profile_index = None
35
+
36
+# ----------------------------------------------------- GUI objects
37
+class RenderFilePanel():
38
+
39
+    def __init__(self):
40
+
41
+        self.out_folder = Gtk.FileChooserButton(_("Select Folder"))
42
+        self.out_folder.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
43
+        self.out_folder.set_current_folder(os.path.expanduser("~") + "/")
44
+        self.out_folder.set_local_only(True)
45
+        out_folder_row = guiutils.get_two_column_box(Gtk.Label(label=_("Folder:")), self.out_folder, 60)
46
+                              
47
+        self.movie_name = Gtk.Entry()
48
+        self.movie_name.set_text("movie")
49
+        self.extension_label = Gtk.Label()
50
+            
51
+        name_box = Gtk.HBox(False, 8)
52
+        name_box.pack_start(self.movie_name, True, True, 0)
53
+        name_box.pack_start(self.extension_label, False, False, 0)
54
+          
55
+        movie_name_row = guiutils.get_two_column_box(Gtk.Label(label=_("Name:")), name_box, 60)
56
+
57
+        self.vbox = Gtk.VBox(False, 2)
58
+        self.vbox.pack_start(out_folder_row, False, False, 0)
59
+        self.vbox.pack_start(movie_name_row, False, False, 0)
60
+
61
+        self.out_folder.set_tooltip_text(_("Select folder to place rendered file in"))
62
+        self.movie_name.set_tooltip_text(_("Give name for rendered file"))
63
+        
64
+
65
+class RenderTypePanel():
66
+    
67
+    def __init__(self, render_type_changed_callback, preset_selection_changed_callback):
68
+        self.type_label = Gtk.Label(label=_("Type:"))
69
+        self.presets_label = Gtk.Label(label=_("Presets:")) 
70
+        
71
+        self.type_combo = Gtk.ComboBoxText() # filled later when current sequence known
72
+        self.type_combo.append_text(_("User Defined"))
73
+        self.type_combo.append_text(_("Preset File type"))
74
+        self.type_combo.set_active(0)
75
+        self.type_combo.connect('changed', lambda w: render_type_changed_callback(w))
76
+    
77
+        self.presets_selector = PresetEncodingsSelector(preset_selection_changed_callback)
78
+
79
+        self.vbox = Gtk.VBox(False, 2)
80
+        self.vbox.pack_start(guiutils.get_two_column_box(self.type_label,
81
+                                                         self.type_combo, 80), 
82
+                                                         False, False, 0)
83
+        self.vbox.pack_start(guiutils.get_two_column_box(self.presets_label,
84
+                                                         self.presets_selector.widget, 80), 
85
+                                                         False, False, 0)
86
+
87
+
88
+class RenderProfilePanel():
89
+
90
+    def __init__(self, out_profile_changed_callback):
91
+        self.use_project_label = Gtk.Label(label=_("Use Default Profile:"))
92
+
93
+        self.out_profile_info_box = ProfileInfoBox() # filled later when current sequence known
94
+
95
+        self.use_project_profile_check = Gtk.CheckButton()
96
+        self.use_project_profile_check.set_active(True)
97
+        self.use_project_profile_check.connect("toggled", self.use_project_check_toggled)
98
+
99
+        self.out_profile_combo = ProfileSelector(out_profile_changed_callback)
100
+
101
+        use_project_profile_row = Gtk.HBox()
102
+        use_project_profile_row.pack_start(self.use_project_label,  False, False, 0)
103
+        use_project_profile_row.pack_start(self.use_project_profile_check,  False, False, 0)
104
+        use_project_profile_row.pack_start(Gtk.Label(), True, True, 0)
105
+    
106
+        self.vbox = Gtk.VBox(False, 2)
107
+        self.vbox.pack_start(use_project_profile_row, False, False, 0)
108
+        self.vbox.pack_start(self.out_profile_combo.widget, False, False, 0)
109
+        self.vbox.pack_start(self.out_profile_info_box, False, False, 0)
110
+
111
+    def set_sensitive(self, value):
112
+        self.use_project_profile_check.set_sensitive(value)
113
+        self.use_project_label.set_sensitive(value)
114
+        self.out_profile_combo.widget.set_sensitive(value)
115
+        
116
+    def use_project_check_toggled(self, checkbutton):
117
+        self.out_profile_combo.widget.set_sensitive(checkbutton.get_active() == False)
118
+        if checkbutton.get_active() == True:
119
+            self.out_profile_combo.widget.set_active(default_profile_index)
120
+            #_display_default_profile()
121
+            
122
+
123
+class RenderEncodingPanel():
124
+    
125
+    def __init__(self, extension_label):
126
+        self.quality_selector = RenderQualitySelector()
127
+        self.quality_selector.widget.set_size_request(110, 34)
128
+        self.quality_selector.update_quality_selection(0)
129
+        self.audio_desc = Gtk.Label()
130
+        self.encoding_selector = RenderEncodingSelector(self.quality_selector,
131
+                                                        extension_label,
132
+                                                        self.audio_desc)
133
+        self.encoding_selector.encoding_selection_changed()
134
+
135
+        quality_row  = Gtk.HBox()
136
+        quality_row.pack_start(self.quality_selector.widget, False, False, 0)
137
+        quality_row.pack_start(Gtk.Label(), True, False, 0)
138
+
139
+        self.vbox = Gtk.VBox(False, 2)
140
+        self.vbox.pack_start(self.encoding_selector.widget, False, False, 0)
141
+        self.vbox.pack_start(quality_row, False, False, 0)
142
+
143
+    def set_sensitive(self, value):
144
+        self.quality_selector.widget.set_sensitive(value)
145
+        self.audio_desc.set_sensitive(value)
146
+        self.speaker_image.set_sensitive(value)
147
+        self.encoding_selector.widget.set_sensitive(value)
148
+
149
+
150
+class ProfileSelector():
151
+    def __init__(self, out_profile_changed_callback=None):
152
+        self.widget = Gtk.ComboBoxText() # filled later when current sequence known
153
+        if out_profile_changed_callback != None:
154
+            self.widget.connect('changed', lambda w:  out_profile_changed_callback(w))
155
+        self.widget.set_sensitive(False)
156
+        self.widget.set_tooltip_text(_("Select render profile"))
157
+        
158
+    def fill_options(self):
159
+        self.widget.get_model().clear()
160
+        #self.widget.append_text(current_sequence().profile.description())
161
+        profiles = mltprofiles.get_profiles()
162
+        for profile in profiles:
163
+            self.widget.append_text(profile[0])
164
+        self.widget.set_active(default_profile_index)
165
+
166
+
167
+class RenderQualitySelector():
168
+    """
169
+    Component displays quality option relevant for encoding slection.
170
+    """
171
+    def __init__(self):
172
+        self.widget = Gtk.ComboBoxText()
173
+        self.widget.set_tooltip_text(_("Select Render quality"))
174
+
175
+    def update_quality_selection(self, enc_index):
176
+        encoding = renderconsumer.encoding_options[enc_index]
177
+        
178
+        self.widget.get_model().clear()
179
+        for quality_option in encoding.quality_options:
180
+            self.widget.append_text(quality_option.name)
181
+
182
+        if encoding.quality_default_index != None:
183
+            self.widget.set_active(encoding.quality_default_index)
184
+        else:
185
+            self.widget.set_active(0)
186
+
187
+
188
+class PresetEncodingsSelector():
189
+    
190
+     def __init__(self, selection_changed_callback):
191
+        self.widget = Gtk.ComboBoxText()
192
+        encs = renderconsumer.non_user_encodings
193
+        
194
+        if disable_audio_encoding == True:
195
+            encs = renderconsumer.get_video_non_user_encodigs()
196
+        
197
+        for encoding in encs:
198
+            self.widget.append_text(encoding.name)
199
+        
200
+        self.widget.set_active(0)
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/trackaction.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/trackaction.py Changed
28
 
1
@@ -29,6 +29,7 @@
2
 import editorstate
3
 from editorstate import get_track
4
 from editorstate import current_sequence
5
+import snapping
6
 import tlinewidgets
7
 import updater
8
 
9
@@ -119,10 +120,17 @@
10
     if msg == "all":
11
         editorstate.display_all_audio_levels = True
12
         updater.repaint_tline()
13
-    else:
14
+    elif msg == "on request":
15
         editorstate.display_all_audio_levels = False
16
         current_sequence().drop_audio_levels()
17
         updater.repaint_tline()
18
+    elif msg == "snapping":
19
+        snapping.snapping_on = widget.get_active()
20
+    elif msg == "magnet":
21
+        snapping.show_magnet_icon = widget.get_active()
22
+    else: # media thumbnails
23
+        editorstate.display_clip_media_thumbnails = widget.get_active()
24
+        updater.repaint_tline()
25
 
26
 # ------------------------------------------------------------- mouse events
27
 def track_active_switch_pressed(data):
28
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/translations.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/translations.py Changed
11
 
1
@@ -75,6 +75,9 @@
2
         print "Use OS locale language."
3
         lang = gettext.translation(APP_NAME, locale_path, languages=langs, fallback=True)
4
 
5
+    # Un-comment for translations test
6
+    #lang = gettext.translation(APP_NAME, locale_path, languages=["fi"], fallback=True)
7
+    
8
     lang.install(APP_NAME) # makes _() a build-in available in all modules without imports
9
 
10
 def get_filter_name(f_name):
11
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/trimmodes.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/trimmodes.py Changed
201
 
1
@@ -29,6 +29,7 @@
2
 import editorstate
3
 from editorstate import current_sequence
4
 from editorstate import PLAYER
5
+from editorstate import EDIT_MODE
6
 import gui
7
 import tlinewidgets
8
 import updater
9
@@ -59,6 +60,13 @@
10
 # This function is set when trim modes are entered to be to the "edit init func for" the entered trim mode.
11
 set_no_edit_mode_func = None
12
 
13
+# Sub modes for handling mouse vs. keyboard edits
14
+NOTHING_ON = 0
15
+MOUSE_EDIT_ON = 1
16
+KEYB_EDIT_ON = 2
17
+
18
+submode = NOTHING_ON
19
+
20
 
21
 # ------------------------------------ module functions       
22
 def _get_trim_edit(track, frame):
23
@@ -225,6 +233,131 @@
24
         set_no_edit_mode_func()
25
 
26
 
27
+#----------------------------------------------------- keyboard events
28
+def left_arrow_pressed(ctrl_pressed):
29
+    global submode
30
+    if submode == MOUSE_EDIT_ON:
31
+        return
32
+        
33
+    submode = KEYB_EDIT_ON
34
+    delta = 1
35
+    if ctrl_pressed:
36
+        delta = 10
37
+        
38
+    if EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
39
+        _one_roll_trim_left(delta)
40
+    elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
41
+        _tworoll_trim_left(delta)
42
+    elif EDIT_MODE() == editorstate.SLIDE_TRIM:
43
+        _slide_trim_left(delta)
44
+        
45
+def right_arrow_pressed(ctrl_pressed):
46
+    global submode
47
+    if submode == MOUSE_EDIT_ON:
48
+        return
49
+        
50
+    submode = KEYB_EDIT_ON
51
+    delta = 1
52
+    if ctrl_pressed:
53
+        delta = 10
54
+        
55
+    if EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
56
+        _one_roll_trim_right(delta)
57
+    elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
58
+        _tworoll_trim_right(delta)
59
+    elif EDIT_MODE() == editorstate.SLIDE_TRIM:
60
+        _slide_trim_right(delta)
61
+
62
+def enter_pressed():
63
+    global submode
64
+    if submode != KEYB_EDIT_ON:
65
+        return
66
+
67
+    if EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
68
+        _one_roll_enter_edit()
69
+    elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
70
+        _tworoll_enter_edit()
71
+    elif EDIT_MODE() == editorstate.SLIDE_TRIM:
72
+        _slide_enter_edit()
73
+
74
+    submode = NOTHING_ON
75
+
76
+def _one_roll_trim_left(delta):
77
+    # Get legal edit frame for overlay display
78
+    global edit_data
79
+    frame = edit_data["selected_frame"] - delta
80
+    frame = _legalize_one_roll_trim(frame, edit_data["trim_limits"])
81
+    edit_data["selected_frame"] = frame
82
+    
83
+    PLAYER().seek_frame(frame)
84
+    
85
+def _one_roll_trim_right(delta):
86
+    # Get legal edit frame for overlay display
87
+    global edit_data
88
+    frame = edit_data["selected_frame"] + delta
89
+    frame = _legalize_one_roll_trim(frame, edit_data["trim_limits"])
90
+    edit_data["selected_frame"] = frame
91
+    
92
+    PLAYER().seek_frame(frame)
93
+    
94
+def _one_roll_enter_edit():
95
+    frame = edit_data["selected_frame"]
96
+    _do_one_roll_trim_edit(frame)
97
+
98
+def _tworoll_trim_left(delta):
99
+    global edit_data
100
+    frame = edit_data["selected_frame"] - delta
101
+    frame = _legalize_two_roll_trim(frame, edit_data["trim_limits"])
102
+    edit_data["selected_frame"] = frame
103
+
104
+    PLAYER().seek_frame(frame)
105
+
106
+def _tworoll_trim_right(delta):
107
+    global edit_data
108
+    frame = edit_data["selected_frame"] + delta
109
+    frame = _legalize_two_roll_trim(frame, edit_data["trim_limits"])
110
+    edit_data["selected_frame"] = frame
111
+
112
+    PLAYER().seek_frame(frame)
113
+
114
+def _tworoll_enter_edit():
115
+    _do_two_roll_edit(edit_data["selected_frame"])
116
+
117
+def _slide_trim_left(delta):
118
+    global edit_data
119
+    try:
120
+        frame = edit_data["keyboard_selected_frame"]
121
+        edit_data["keyboard_selected_frame"] = frame - delta
122
+    except:
123
+        try:
124
+            edit_data["keyboard_selected_frame"] = edit_data["press_start"] - delta
125
+        except:
126
+            trim_limits = edit_data["trim_limits"]
127
+            edit_data["press_start"] = trim_limits["clip_start"] + 1 # this can be anything the relevant thing here is mouse delta
128
+            edit_data["keyboard_selected_frame"] = edit_data["press_start"] - delta
129
+
130
+    display_frame = _update_slide_trim_for_mouse_frame(edit_data["keyboard_selected_frame"])
131
+    PLAYER().seek_frame(display_frame)
132
+
133
+def _slide_trim_right(delta):
134
+    global edit_data
135
+    try:
136
+        frame = edit_data["keyboard_selected_frame"]
137
+        edit_data["keyboard_selected_frame"] = frame + delta
138
+    except:
139
+        try:
140
+            edit_data["keyboard_selected_frame"] = edit_data["press_start"] + delta
141
+        except:
142
+            trim_limits = edit_data["trim_limits"]
143
+            edit_data["press_start"] = trim_limits["clip_start"] + 1 # this can be anything the relevant thing here is mouse delta
144
+            edit_data["keyboard_selected_frame"] = edit_data["press_start"] + delta
145
+
146
+    display_frame = _update_slide_trim_for_mouse_frame(edit_data["keyboard_selected_frame"])
147
+    PLAYER().seek_frame(display_frame)
148
+
149
+def _slide_enter_edit():
150
+    _do_slide_edit()
151
+    
152
 # ------------------------------------- ONE ROLL TRIM EVENTS
153
 def set_oneroll_mode(track, current_frame=-1, editing_to_clip=None):
154
     """
155
@@ -301,7 +434,7 @@
156
     """
157
     User presses mouse when in one roll mode.
158
     """
159
-    global mouse_disabled
160
+    global mouse_disabled, submode
161
 
162
     if not _pressed_on_edited_track(event.y):
163
         track = tlinewidgets.get_track(event.y)
164
@@ -312,6 +445,7 @@
165
             else:
166
                 set_no_edit_mode_func() # further mouse events are handled at editevent.py
167
         else:
168
+            submode = MOUSE_EDIT_ON # to stop entering keyboard edits until mouse released
169
             if not editorpersistance.prefs.quick_enter_trims:
170
                 # new trim inited, editing non-active until release
171
                 tlinewidgets.trim_mode_in_non_active_state = True
172
@@ -333,6 +467,7 @@
173
             else:
174
                 set_no_edit_mode_func() # no furter mouse events will come here
175
         else:
176
+            submode = MOUSE_EDIT_ON # to stop entering keyboard edits until mouse released
177
             if not editorpersistance.prefs.quick_enter_trims:
178
                 # new trim inited, editing non-active until release
179
                 tlinewidgets.trim_mode_in_non_active_state = True
180
@@ -370,7 +505,8 @@
181
     """
182
     User releases mouse when in one roll mode.
183
     """
184
-    global mouse_disabled
185
+    global mouse_disabled, submode
186
+    submode = NOTHING_ON # we can now enter keyboard edits 
187
     if mouse_disabled:
188
         mouse_disabled = False
189
         # we may have been in non active state because the clip being edited was changed
190
@@ -589,7 +725,9 @@
191
         _attempt_reinit_tworoll(event, frame)
192
         return
193
 
194
-    global edit_data
195
+    global edit_data, submode
196
+    submode = MOUSE_EDIT_ON
197
+
198
     frame = _legalize_two_roll_trim(frame, edit_data["trim_limits"])
199
     edit_data["selected_frame"] = frame
200
     PLAYER().seek_frame(frame)
201
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/updater.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/updater.py Changed
12
 
1
@@ -102,7 +102,9 @@
2
 
3
 
4
 # --------------------------------- player
5
-def refresh_player():
6
+def refresh_player(e):
7
+    if (e.changed_mask & (~ Gdk.WindowState.FOCUSED)) == 0:
8
+        return
9
     # First event is initial window displayed event.
10
     # Last closing event needs to be blocked by setting this flag
11
     # before calling window hide
12
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/utils.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/utils.py Changed
191
 
1
@@ -79,6 +79,8 @@
2
             event.wait(delay)
3
         self.exited = True
4
 
5
+        
6
+        
7
 # -------------------------------- UTIL FUNCTIONS
8
 def fps():
9
     return editorstate.PROJECT().profile.fps()
10
@@ -153,7 +155,7 @@
11
         text = "A" + str(sequence.first_video_index - track.id)
12
     return text
13
 
14
-def get_media_source_file_filter():
15
+def get_media_source_file_filter(include_audio=True):
16
     # No idea if these actually play or not, except images mime types
17
     f = Gtk.FileFilter()
18
     f.set_name("Media MIME types")
19
@@ -182,39 +184,40 @@
20
     f.add_mime_type("video/3gpp")
21
     f.add_mime_type("video/webm")
22
     
23
-    f.add_mime_type("audio/aac")
24
-    f.add_mime_type("audio/ac3")
25
-    f.add_mime_type("audio/AMR")
26
-    f.add_mime_type("audio/ogg")
27
-    f.add_mime_type("audio/midi")
28
-    f.add_mime_type("audio/mp2")
29
-    f.add_mime_type("audio/mp3")
30
-    f.add_mime_type("audio/mp4")
31
-    f.add_mime_type("audio/mpeg")
32
-    f.add_mime_type("audio/ogg")
33
-    f.add_mime_type("audio/vnd.rn-realaudio")
34
-    f.add_mime_type("audio/vorbis")
35
-    f.add_mime_type("audio/x-adpcm")
36
-    f.add_mime_type("audio/x-aifc")
37
-    f.add_mime_type("audio/x-aiff")
38
-    f.add_mime_type("audio/x-aiffc")
39
-    f.add_mime_type("audio/x-flac")
40
-    f.add_mime_type("audio/x-flac+ogg")
41
-    f.add_mime_type("audio/x-m4b")
42
-    f.add_mime_type("audio/x-matroska")
43
-    f.add_mime_type("audio/x-ms-wma")
44
-    f.add_mime_type("audio/x-oggflac")
45
-    f.add_mime_type("audio/x-ms-asx")
46
-    f.add_mime_type("audio/x-ms-wma")
47
-    f.add_mime_type("audio/x-ms-wma")
48
-    f.add_mime_type("audio/x-gsm")
49
-    f.add_mime_type("audio/x-riff")
50
-    f.add_mime_type("audio/x-speex")
51
-    f.add_mime_type("audio/x-speex+ogg")
52
-    f.add_mime_type("audio/x-tta")
53
-    f.add_mime_type("audio/x-voc")
54
-    f.add_mime_type("audio/x-vorbis+ogg")
55
-    f.add_mime_type("audio/x-wav")
56
+    if include_audio == True:
57
+        f.add_mime_type("audio/aac")
58
+        f.add_mime_type("audio/ac3")
59
+        f.add_mime_type("audio/AMR")
60
+        f.add_mime_type("audio/ogg")
61
+        f.add_mime_type("audio/midi")
62
+        f.add_mime_type("audio/mp2")
63
+        f.add_mime_type("audio/mp3")
64
+        f.add_mime_type("audio/mp4")
65
+        f.add_mime_type("audio/mpeg")
66
+        f.add_mime_type("audio/ogg")
67
+        f.add_mime_type("audio/vnd.rn-realaudio")
68
+        f.add_mime_type("audio/vorbis")
69
+        f.add_mime_type("audio/x-adpcm")
70
+        f.add_mime_type("audio/x-aifc")
71
+        f.add_mime_type("audio/x-aiff")
72
+        f.add_mime_type("audio/x-aiffc")
73
+        f.add_mime_type("audio/x-flac")
74
+        f.add_mime_type("audio/x-flac+ogg")
75
+        f.add_mime_type("audio/x-m4b")
76
+        f.add_mime_type("audio/x-matroska")
77
+        f.add_mime_type("audio/x-ms-wma")
78
+        f.add_mime_type("audio/x-oggflac")
79
+        f.add_mime_type("audio/x-ms-asx")
80
+        f.add_mime_type("audio/x-ms-wma")
81
+        f.add_mime_type("audio/x-ms-wma")
82
+        f.add_mime_type("audio/x-gsm")
83
+        f.add_mime_type("audio/x-riff")
84
+        f.add_mime_type("audio/x-speex")
85
+        f.add_mime_type("audio/x-speex+ogg")
86
+        f.add_mime_type("audio/x-tta")
87
+        f.add_mime_type("audio/x-voc")
88
+        f.add_mime_type("audio/x-vorbis+ogg")
89
+        f.add_mime_type("audio/x-wav")
90
     f.add_mime_type("audio/annodex")
91
 
92
     f.add_mime_type("image/bmp")
93
@@ -227,6 +230,37 @@
94
 
95
     return f
96
 
97
+def get_video_source_file_filter():
98
+    # No idea if these actually play or not, except images mime types
99
+    f = Gtk.FileFilter()
100
+    f.set_name("Video files")
101
+    f.add_mime_type("image*")
102
+    f.add_mime_type("video*")
103
+    f.add_mime_type("audio*")
104
+    f.add_mime_type("video/x-theora+ogg")
105
+    f.add_mime_type("video/x-sgi-movie")
106
+    f.add_mime_type("video/ogg")
107
+    f.add_mime_type("video/x-ogm")
108
+    f.add_mime_type("video/x-ogm+ogg")
109
+    f.add_mime_type("video/x-ms-asf")
110
+    f.add_mime_type("video/x-ms-wmv")
111
+    f.add_mime_type("video/x-msvideo")
112
+    f.add_mime_type("video/x-matroska")
113
+    f.add_mime_type("video/x-flv")
114
+    f.add_mime_type("video/vnd.rn-realvideo")
115
+    f.add_mime_type("video/quicktime")
116
+    f.add_mime_type("video/ogg")
117
+    f.add_mime_type("video/mpeg")
118
+    f.add_mime_type("video/mp4")
119
+    f.add_mime_type("video/mp2t")
120
+    f.add_mime_type("video/isivideo")
121
+    f.add_mime_type("video/dv")
122
+    f.add_mime_type("video/annodex")
123
+    f.add_mime_type("video/3gpp")
124
+    f.add_mime_type("video/webm")
125
+
126
+    return f
127
+
128
 def get_image_sequence_file_filter():
129
     f = Gtk.FileFilter()
130
     f.set_name("Image files")
131
@@ -311,7 +345,7 @@
132
 
133
 def get_unique_name_for_audio_levels_file(media_file_path, profile):
134
     size_str = str(os.path.getsize(media_file_path))
135
-    fps_str = str(profile.fps())
136
+    fps_str = str(profile.description())
137
     file_name = md5.new(media_file_path + size_str + fps_str).hexdigest()
138
     return file_name
139
     
140
@@ -323,6 +357,9 @@
141
     else:
142
         return os.getenv("HOME") + "/.flowblade/"
143
 
144
+def get_phantom_disk_cache_folder():
145
+    return get_hidden_user_dir_path() +  appconsts.NODE_COMPOSITORS_DIR + "/" + appconsts.PHANTOM_DISK_CACHE_DIR
146
+
147
 def get_hidden_screenshot_dir_path():
148
     return get_hidden_user_dir_path() + "screenshot/"
149
 
150
@@ -359,6 +396,40 @@
151
 
152
     return resource_name_str
153
 
154
+def get_file_producer_info(file_producer):
155
+    clip = file_producer
156
+    
157
+    info = {}
158
+    info["width"] = clip.get_int("width")
159
+    info["height"] = clip.get_int("height")
160
+    info["length"]  = clip.get_length()
161
+    
162
+    video_index = clip.get_int("video_index")
163
+    audio_index = clip.get_int("audio_index")
164
+    long_video_property = "meta.media." + str(video_index) + ".codec.long_name"
165
+    long_audio_property = "meta.media." + str(audio_index) + ".codec.long_name"
166
+    sample_rate_property = "meta.media." + str(audio_index) + ".codec.sample_rate"
167
+    channels_property = "meta.media." + str(audio_index) +  ".codec.channels"
168
+    
169
+    info["vcodec"] = clip.get(str(long_video_property))
170
+    info["acodec"] = clip.get(str(long_audio_property))
171
+    info["channels"] = clip.get_int(str(channels_property))
172
+    info["frequency"] =  clip.get_int(str(sample_rate_property))
173
+    frame = clip.get_frame()
174
+    info["fps_num"] = frame.get_double("meta.media.frame_rate_num")
175
+    info["fps_den"] = frame.get_double("meta.media.frame_rate_den")
176
+    info["progressive"] = frame.get_int("meta.media.progressive") == 1
177
+    info["top_field_first"] = frame.get_int("meta.media.top_field_first") == 1
178
+    
179
+    return info
180
+
181
+def is_media_file(file_path):
182
+    file_type = get_file_type(file_path)
183
+    if file_type == "unknown":
184
+        return False
185
+    else:
186
+        return True
187
+
188
 # File exntension lists
189
 _audio_file_extensions = [  "act",
190
                             "aif",
191
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/vieweditor/vieweditor.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/vieweditor/vieweditor.py Changed
20
 
1
@@ -64,7 +64,7 @@
2
         self.edit_layers = []
3
         self.active_layer = None
4
         self.edit_target_layer = None
5
-        
6
+
7
         self.change_active_layer_for_hit = True
8
         self.active_layer_changed_listener = None # interface: listener(new_active_index)
9
                                                   # note: vieweditor calls activate_layer( ) when non-active layer hit
10
@@ -235,7 +235,9 @@
11
             self.origo = (0.0, 0.0)
12
             img_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.profile_w, self.profile_h)
13
             cr = cairo.Context(img_surface)
14
+            #cr.translate(-1.0 /ox, 0.0)
15
 
16
+ 
17
         for editorlayer in self.edit_layers:
18
             if editorlayer.visible:
19
                 editorlayer.draw(cr, self.write_out_layers, self.draw_overlays)
20
flowblade-1.4.tar.gz/flowblade-trunk/Flowblade/vieweditor/vieweditorlayer.py -> flowblade-1.8.tar.gz/flowblade-trunk/Flowblade/vieweditor/vieweditorlayer.py Changed
16
 
1
@@ -238,8 +238,13 @@
2
     def draw(self, cr, write_out_layers, draw_overlays):
3
         x, y = self.edit_point_shape.get_panel_point(0, self.view_editor)
4
         rotation = self.edit_point_shape.get_first_two_points_rotation_angle()
5
-        xscale = self.view_editor.scale * self.view_editor.aspect_ratio
6
+        xscale = self.view_editor.scale #* self.view_editor.aspect_ratio
7
         yscale = self.view_editor.scale
8
+        # x fo write out image is on different place because computer screen has box pixels, 
9
+        # some video formats do not
10
+        if write_out_layers == True:
11
+            x = x / self.view_editor.aspect_ratio
12
+            
13
         self.text_layout.draw_layout(cr, x, y, rotation, xscale, yscale)
14
 
15
         if self.update_rect:
16
flowblade-1.4.tar.gz/flowblade-trunk/docs/CREATING_TRANSLATION.md -> flowblade-1.8.tar.gz/flowblade-trunk/docs/CREATING_TRANSLATION.md Changed
64
 
1
@@ -1,16 +1,24 @@
2
-# Contributing a translation
3
+# Creating a translation
4
 
5
 If you would like to have Flowblade translated into your language you can help by contributing a translation of Flowblade in your language.
6
 
7
-### Installing developer version of Flowblade
8
+Flowblade uses the standard [GNU "gettext" utilities](http://www.gnu.org/software/gettext/manual/gettext.html) to translate the application. GNU "gettext" is a relatively complex tool, but **Flowblade provides a set of scripts that make it easier to create translations** without using "gettext" directly.
9
 
10
-To create a translation you should probably first install the repository version of Flowblade so that you can edit and compile the translation file ``Flowblade.po``, see [Install Instructions](https://github.com/jliljebl/flowblade/blob/master/flowblade-trunk/docs/INSTALLING.md).
11
+### Steps Overview
12
+1. Use **git** to pull repository version of Flowblade
13
+2. Use the provided scripts to create a translation template for your language
14
+3. Edit the created template to create the translation and compile **.mo** file from it to see your work
15
+4. Send the created **.po** file to project lead
16
+
17
+### 1. Use **git** to pull repository version of Flowblade
18
+
19
+To create a translation you should probably first install the repository version of Flowblade using **git** so that you can edit and compile the translation file ``Flowblade.po``, see [Install Instructions](https://github.com/jliljebl/flowblade/blob/master/flowblade-trunk/docs/INSTALLING.md).
20
 
21
-Flowblade uses the standard [GNU "gettext" utilities](http://www.gnu.org/software/gettext/manual/gettext.html) to translate the application. GNU "gettext" is a relatively complex tool, but **Flowblade provides a set of scripts that make it easier to create translations** without using "gettext" directly.
22
 
23
-### Creating a translation ###
24
 
25
-  * Launch repository version of Flowblade and select *Help -> Environment* from menu to see the two letter locale code for your OS install. For example *fr* for French, *fi* for Finnish etc. Information is under the header *General*.
26
+### 2. Use the provided scripts to create a translation template for your language
27
+
28
+  * Open Flowblade and select *Help -> Runtime Environment* from menu to see the *two letter locale code* for your OS install. For example *fr* for French, *fi* for Finnish etc. Information is under the header *General*.
29
   * Open terminal in folder ``.../flowblade-trunk/Flowblade/locale`` that can be found in the folder you installed repository version of Flowblade in.
30
   * To create a new translation give a command in the terminal:
31
 ```bash
32
@@ -18,7 +26,7 @@
33
 ```
34
  in which LANGUAGE_CODE is the two letter language code for your locale.
35
   
36
-### Editing translation ###
37
+### 3. Edit the created template to create the translation and compile **.mo** file from it to see your work ###
38
 
39
   * A folder named with the LANGUAGE_CODE for your language can be found in the ``/locale`` folder
40
   * Inside that folder is a ``/LC_MESSAGES`` folder in which there is a file called ``Flowblade.po``. This is the file used to create the translation.
41
@@ -34,12 +42,17 @@
42
 ```
43
   * Launch repository version of Flowblade to view your translations.
44
 
45
-### Updating translation ###
46
+
47
+
48
+### 4. Contributing a translation
49
+Send the created ``Flowblade.po`` file to janne.liljeblad@gmail.com or submit a Github pull request. Please mention words Flowblade, translation and the LANGUAGE_CODE in the subject line. Translation will be in the next release.
50
+
51
+
52
+## Updating translation ##
53
+If a translation already exists and you want to update it:
54
+
55
  * Go to the */locale* folder and give command:
56
 ```bash
57
 ./update_language LANGUAGE_CODE
58
 ```
59
- * Translate application as described above in paragraph **Editing translation**
60
-
61
-### Contributing a translation
62
-Send the created ``Flowblade.po`` file to janne.liljeblad@gmail.com or submit a Github pull request. Please mention words Flowblade, translation and the LANGUAGE_CODE in the subject line. Translation will be in the next release.
63
+ * Translate application as described above.
64
flowblade-1.4.tar.gz/flowblade-trunk/docs/DEPENDENCIES.md -> flowblade-1.8.tar.gz/flowblade-trunk/docs/DEPENDENCIES.md Changed
23
 
1
@@ -9,10 +9,15 @@
2
 | python 2.7 >=| Language and interpreter |
3
 | frei0r-plugins | Additional video filters |
4
 | swh-plugins | Additional audio filters |
5
-| python-cairo | Cairo bindings |
6
+| python-gi-cairo | Gi Cairo bindings |
7
 | python-numpy | Math and arrays library |
8
 | python-pil | PIL image manipulation library |
9
 | librsvg2-common | svg support |
10
+| gmic | framework for image processing |
11
+| gir1.2-glib-2.0 | Glib |
12
+| gir1.2-gtk-3.0 | Gtk toolkit |
13
+| gir1.2-pango-1.0 | Pango text lib |
14
+| gir1.2-gdkpixbuf-2.0 | Image support |
15
 
16
 # Dropped  Dependencies #
17
 
18
@@ -24,3 +29,4 @@
19
 | gtk2-engines-pixbuf |  0.6   |  1.2 |
20
 | python-gnome2 |  0.6   |  1.2 |
21
 | python-gobject-2 |  0.6   |  1.2 |
22
+| python-cairo |  0.6   |  1.6 |
23
flowblade-1.4.tar.gz/flowblade-trunk/docs/FAQ.md -> flowblade-1.8.tar.gz/flowblade-trunk/docs/FAQ.md Changed
36
 
1
@@ -3,8 +3,10 @@
2
 **Contents**
3
 
4
   1. [Crop filter does not work](./FAQ.md####crop-filter-does-not-work)
5
-  2. [Will there be Windows or OSX versions](./FAQ.md####will-there-be windows-or-OSX-versions)
6
-  
7
+  2. [How can I move clips around freely?](./FAQ.md####how-can-i-move-clips-around-freely)
8
+  3. [Will there be Windows or OSX versions?](./FAQ.md####will-there-be windows-or-OSX-versions)
9
+  4. [Rendering with a profile with different framerate changes video playback speed and loses audio sync](./FAQ.md####rendering-with-a-profile-with-different-framerate-changes-video playback-speed-and-loses-audio-sync)
10
+
11
 #### Crop filter does not work
12
 
13
 Are you trying zoom in a bit and use part of the image instead of the whole image?
14
@@ -12,7 +14,20 @@
15
 
16
 If you are trying to crop an image in the sense that you want to cut part of the image out, then you must use a Compositor and composite the image you are trying to crop on top of another image or perhaps a black color producer.
17
 
18
-  
19
+
20
+#### How can I move clips around freely?
21
+
22
+Use the **Overwrite** tool.
23
+
24
+Click on timeline and press **2** on keyboard or use the **Tool Select Menu** in the middlebar next to the timecode display.
25
+
26
 #### Will there be Windows or OSX versions?
27
 
28
 These are not currently planned. If in the future the port effort is reasonable, does not have adverse effects on the code base and someone provides quality patches, then those patches can probably be accepted.
29
+
30
+
31
+#### Rendering with a profile with different framerate changes video playback speed and loses audio sync ####
32
+
33
+Yes, this will happen. When rendering the video frames are just copied, no complex slowdown/speedup prosessing is done, and audio is **not** resampled.
34
+
35
+To maintain sync and playback both Project Profile and Render Profile both need to match the frame rate of original material.  
36
flowblade-1.8.tar.gz/flowblade-trunk/docs/Flowblade-Patch-PlayPause.pdf Added
flowblade-1.4.tar.gz/flowblade-trunk/docs/INSTALLING.md -> flowblade-1.8.tar.gz/flowblade-trunk/docs/INSTALLING.md Changed
58
 
1
@@ -3,20 +3,33 @@
2
 
3
 ### Installing using .deb package
4
 
5
-**First download .deb file** for Flowblade 1.4 from <a href="https://www.dropbox.com/s/xe94cjwmf195de2/flowblade-1.4.0-1_all.deb?dl=0">here.</a>
6
+#### Step 1. Download and install .deb 
7
+**First download .deb file** for Flowblade 1.8 from <a href="https://www.dropbox.com/s/onrdoivia6t0rjd/flowblade-1.8.0-1_all.deb?dl=0">here.</a>
8
+
9
+Double click on <b>.deb</b> file to install it. 
10
+
11
+On some systems double clicking may not work (on Ubuntu it has sometimes istalled old version from repository), and you need to install <b>.deb</b> file using terminal:
12
 
13
 <ul>
14
-    <li>Double Click on the downloaded .deb file to install.</li>
15
-    <li>On at least <b>Linux Mint 17</b> you will need to install dependencies separately with command:</li>
16
+   <li>    <p>Open terminal in the directory you saved the  downloaded <b>.deb</b> file. Give command: </li>
17
 </ul>
18
+```bash
19
+sudo dpkg -i ./flowblade-1.8.0-1_all.deb
20
+```
21
 
22
+#### Step 2. Give some additional commands on terminal
23
+
24
+You may need to give some additional commands on terminal:
25
+<ul>
26
+   <li>Force install all dependencies with command:</li>
27
+</ul>
28
 ```bash
29
-sudo apt-get install -f
30
+   sudo apt-get install -f
31
 ```
32
 
33
-Release has been tested on: <b>Ubuntu 15.10, 14.10, Linux Mint 17 and Debian 8</b>.
34
+Release has been install tested on: <b>Ubuntu 16.04</b>. <b>Linux Mint 18</b> and <b>Debian 8</b>. It should work on all recent Debian based distributions.
35
 
36
-<b><i>Flowblade versions 1.2 and 1.4 are not supported for Ubuntu 14.04, Debian 7 or earlier systems.</i></b> Flowblade uses a GTK3 feature that is not available on those systems. Last GTK2 version 1.0 should work fine and it can be downloaded <a href="https://www.dropbox.com/s/9m2e9whcazjo1l8/flowblade-1.0.0-1_all.deb?dl=0">here.</a>
37
+<b>NOTE: Running a KDEnlive PPA on Ubuntu may cause an uncompatible MLT to be installed and prevent Flowblade from running, more <a href="https://plus.google.com/105369302467641615295/posts/QSKQoPtbLKg">here.</a></b> 
38
 
39
 *Please note these issues with Dropbox download:*
40
 <ul>
41
@@ -52,13 +65,13 @@
42
 
43
 Flowblade is currently a 100% script application, and all the dependencies should be available in popular distributions, so in most cases it should be possible to install and run Flowblade without compiling anything.
44
 
45
-**First download 1.4 tar.gz** source archive file from <a href="https://www.dropbox.com/s/vmu12w36ov2aza8/flowblade-1.4.0.tar.gz?dl=0">here.</a> 
46
+**First download 1.8 tar.gz** source archive file from <a href="https://www.dropbox.com/s/j0f1uzl2grsivzw/flowblade-1.8.0.tar.gz?dl=0">here.</a> 
47
 
48
   * Extract archive into a folder of your choosing
49
   * Install dependencies. See [Dependencies](DEPENDENCIES.md) doc for more information.
50
   * If you have Flowblade installed in your system, you probably have the dependencies installed, unless some new ones have been added.
51
-  * Launch by running script *.../flowblade-1.4.0/flowblade* that was created in the folder where archive was unpacked.
52
-  * Note that if you have Flowblade installed you will need use full path to repository version or navigate to the folder containing launch script and use command "./flowblade" to launch repository version instead of installed version.
53
+  * Launch by running script *.../flowblade-1.8.0/flowblade* that was created in the folder where archive was unpacked.
54
+  * Note that if you have Flowblade installed yu will need use full path to repository version or navigate to the folder containing launch script and use command "./flowblade" to launch repository version instead of installed version.
55
 
56
 *Please note these issues with Dropbox download:*
57
 <ul>
58
flowblade-1.8.tar.gz/flowblade-trunk/docs/KNOWN_ISSUES.md Added
36
 
1
@@ -0,0 +1,34 @@
2
+# Known Issues
3
+
4
+This is list of bugs and defectes that are known to exist, but will probably not be fixed anytime soon.
5
+
6
+#### 1. Selecting clip in timeline often blocks ability to drag / move / select tracks in awesomeWM
7
+
8
+In awesomeWM there are often problems dragging clips. Instead of moving the clip, a file icon appears and is moved. 
9
+
10
+The problem causing the bug is that awesome fires 'leave-notify-event' signals even when mouse has not left the timeline area.
11
+
12
+**Status:** Problem is in another program, cannot be fixed in Flowblade
13
+
14
+#### 2. Audio may be corrupted when first clip is not at complete beginning with H.264/mp4
15
+
16
+Audio output (especially when using H.264 /mp4-codec and mp3 for audio) may be unusable when there is a (small) gap at the very beginning of video. The sound comes out distorted. After moving the first files to the first frame the audio plays correctly.
17
+
18
+**Status:** No work is planned on this. This is almost guaranteed to be MLT or codec issue and as such cannot be fixed within Flowblade.
19
+
20
+#### 3. Changing profile for rendering changes image scaling / positioning for compositors.
21
+
22
+Compositors and filters receive broken image scaling and positioning if project profile is changed for rendering.
23
+
24
+The problem is that the relevant data is saved as absolute pixel values, not as 0-1 normalized floats. Changing the render profile does not change the positioning or scaling correctly, e.g 50 px X-position is different image position for HD and SD images.
25
+
26
+The current proposed solution is to render using original profile and re-render to desired dimensions.
27
+
28
+**Status:** No work is planned on this. An acceptable work around exists, and a fix would require large de-stabilizing changes all over the code base.
29
+
30
+#### 4. mov/xdcam422 clips with high bitrate  (50000kb/s) may not work with proxy editing
31
+This has been reported and a single case has been reproduced.
32
+
33
+**Status:** No work on a fix is planned.
34
+
35
+
36
flowblade-1.4.tar.gz/flowblade-trunk/docs/RELEASE_NOTES.md -> flowblade-1.8.tar.gz/flowblade-trunk/docs/RELEASE_NOTES.md Changed
164
 
1
@@ -1,12 +1,141 @@
2
 # Release Notes #
3
 
4
+## Flowblade 1.8 ##
5
+
6
+**Date: September 2, 2016**
7
+
8
+**Flowblade 1.8** is the twelth release of Flowblade. 
9
+
10
+During this cycle a lot of time was spend on creating a website for the project and on bringing a node compositor tool to Flowblade. Website was succesfully deployed, but the node compositor tool was dropped in final stages of development.
11
+
12
+The node compositor was dropped when I realized that it does not serve any user group particularly well.
13
+
14
+Casual users will find difficult to use node compositors effectively as any non-trivial composition requires creating complex node graphs. On the other hand adcanced users already have alternative FLOSS solutions like Natron and Blender available, and are unlikely to adopt this tool in meaningful numbers.
15
+
16
+Once it became clear that it would require postponing this release quite a bit to do the remaining bugfixing and creating documentation, I decided that the project is best served by allocating resources to other areas of development.
17
+
18
+We did get some good stuff in, and with the next cycle we can hopefully get moving with improved speed of feature development.
19
+
20
+Particular attention will given to the current *Issues* list, with some of the other focus areas being improving integration between tools and timeline, and an attempt to make nested clips available.
21
+
22
+### Flowblade Main Features ###
23
+
24
+* **Keybord trimming with arrow keys** Trim positions can now be moved using arrow keys and trim edit confirmed with pressing Enter key. This is often more convenient and previse then always working with a mouse
25
+* **Clip Snapping** Clips and compositors will now snap to clip ends on adjacent tracks when clips or compositors are moved or their ends dragged. 
26
+* **Clips display media thumbnails** This helps differentiating clips from each other on timeline.
27
+* **EDL export** is now available. Thanks to Github user *tin2tin* for extensive testing on software not available on my system. Unfortunately it became clear that Blender EDL import is buggy.
28
+
29
+### G'MIC Film Emulation Filters ###
30
+
31
+G'MIC Effects tool got an important capability update with the addition of film emulation filters.
32
+
33
+G'MIC Film Emulation Filters change the tones and gamma of the image to resemble different film stocks. Where as other color correction filters available in Flowblade work with luma or R,G,B LUTs, film emulation filters employ much bigger LUTs which are applied to the 3D color space of the image, and can achieve more detailed changes. 
34
+
35
+The results have been quite nice during testing; it is often possible to achive subtle effects that greatly improve the look of the material.
36
+
37
+
38
+### Contributions ###
39
+
40
+In this cycle we got the largest amount of contributions per cycle so far.
41
+
42
+* **Hungarian translation** was provided by Péter Gábor. These take a big amount work and we're always happy to receive a new one.
43
+* **Play/pause toggle with single button** functionality was provided by Github user *dvdlvr*. This has been asked before so a portion of users probably likes it better like. The new behaviour needs to be activated from *Preferences*
44
+* **Titler remembers last save directory** patch by Martin Mois. Before the user needed to always navigate away from the default folder when saving titles.
45
+* **New anti-aliased the monitor control icons and modified the clear marks icon** by Github user *bergamote* improve visuals on that part of the GUI.
46
+
47
+
48
+###  Bugfixes and enhancements ###
49
+* "Change Project" functionality fixed, and works much better now 
50
+* If first loaded media does not match current project profile, user is informed and given option to switch to matching profile.
51
+* Fix assoc file launch from e.g. Nautilus
52
+* Improve missing rendered transition media overlap info
53
+* Compositors can now move by dragging from middle too, not just edges
54
+* Do gi.require() for Gtk and PangoCairo to silence warnings and specify Gtk+ 3
55
+* Make MLT version detection work for two digit version number parts
56
+* Fix adding media while in proxy mode
57
+* Check and give info on IO errors when saving in main app and relinker
58
+* Add keyboard shorcut 'R' for resyncing selected clip or compositor
59
+* Display image sizes for graphics files in info dialogs
60
+* Make CTRL + Mouse toggle media items selection state, not just add to selection
61
+* Make KeyFrameEditor prev button update keuframes info
62
+* Fix updating non-existing clip in effects editor after delete
63
+* Make Compositor GUI edit update keyframe count display
64
+* Add user selectable scope overlay opacity
65
+* Add timeline start indicator triangles
66
+* Remove non-existing files from recents list
67
+* Fix launching uninited renders
68
+* Fix too long filename layout bug in filter editor
69
+* Fix unicode project name bug
70
+* Display warning icons for non-profile-matching video media
71
+* Reset titler for new project
72
+
73
+
74
+
75
+## Flowblade 1.6 ##
76
+
77
+**Date: March 2, 2016**
78
+
79
+**Flowblade 1.6** is the eleventh release of Flowblade. The main feature of this release is the new G'MIC Effects tool.
80
+
81
+### G'MIC effects tool ###
82
+
83
+G'MIC is a full-featured open-source framework for image processing developed by french research scientist David Tschumperlé and others. Its main strength is that it enables creating complex new image filters without writing any compiled code.
84
+
85
+For applications such as Flowblade this makes it possible to offer a wide range of image filtering capabilities using a relatively small amount of managed code.
86
+
87
+A [demo video](https://vimeo.com/157364651) of some features available in the first release is available at Vimeo. This is just the first step, many more filters will come in the future.
88
+
89
+### Other main features in this release ###
90
+
91
+* **Changing project profile is now possible.** This is a feature that was requested by users who felt uneasy about having to commit to a profile at the beginning of the project.
92
+
93
+* **Drag'n'drop of media files from other applications** is a standard feature that has so far been missing from Flowblade.
94
+ 
95
+* **Middlebar was updated** on wider screens as G'MIC, Batch Render Queue and Split Audio buttons were added.
96
+
97
+* **'Sync All Compositors' functionality was added** This can be very useful in situations where a track as a whole is moved in relation to other media.
98
+
99
+For the next release cycle the focus will be on integrating existing technologies to improve Flowblade's capabilites in doing motion graphics. The Natron compositor project offers a lot of promise here, and the exisiting node compositor by myself will be made available in some form.
100
+
101
+Also a project website will be developed during this cycle. The first version is to be made available in a week or two.
102
+
103
+The next cycle will be the longest since 0.16 because of the amount of coding and research needed. The target release date for 1.8 is September 2016.
104
+
105
+####Bugfixes and enhancements####
106
+* Fix set parent clip functionality
107
+* Fix translation scripts (apienk)
108
+* Re-create all media icons always when requested
109
+* Fix dark theme monitor indicator icon
110
+* Fix change to first bin after media load bug
111
+* Remove alpha mode functionality from compositors
112
+* Fix batch render to respect profile selection
113
+* Fix single render to respect changed profile
114
+* Open missing asset project directly from info dialog into Media Relinker on request
115
+* Add Mark In and Mark Out data to clip info dialog
116
+* Remove write env data functionality
117
+* Fix dark theme mute video icon
118
+* Add transition button to TC Middle layout and combine it with edit buttons group
119
+* Fix filter cloning for filters witn non-mlt properties
120
+* Make Titler work better with non-square pixel formats
121
+* Add HD 1080p 60fps profile
122
+* Range Log sorting upgrade and gmic encode view update
123
+* New undo-redo icons (bergamote)
124
+* Render slowmo files from original when using proxy files
125
+* Make possible to render slowmo file from a Range Log item
126
+* RHEL7/CentOS compatibility patch (Martin A. Wielebinski)
127
+* Fix file info fps display
128
+* Make relinker and batchrender use dark theme
129
+* Make single render use dark theme and add percentage display
130
+* New in/out markers (bergamote)
131
+
132
+
133
 ## Flowblade 1.4 ##
134
 
135
 **Date: November 24, 2015**
136
 
137
 **Flowblade 1.4** is the tenth release of Flowblade and the first release after the GTK3 port.
138
 
139
-Most main features in this release are changes to editing model that are designed to make editing more approachable and quicker. It is also notable that a large part of the main features were based on user requests, a first for the project.
140
+Most main features in this release are changes to editing model that were designed to make editing more approachable and quicker. It is also notable that a large part of the main features were based on user requests, a first for the project.
141
 
142
 In the next release cycle features that will be attempted include a G'MIC effects scripting tool, a node compositor tool using an existing code base, a first launch tips window for new users, and a clip snapping feature.
143
 
144
@@ -14,15 +143,15 @@
145
 
146
 ### Main Features in this release ###
147
 
148
-* **Fade/Transition cover delete feature was added.** Selecting a single rendered fade/transition clip and pressing delete will cause the deleted area to covered using material from adjacent clips if such meterial is available. This makes working with single track transitions/fades faster. Previous delete behaviour can be restored using a preference option.
149
+* **Fade/Transition cover delete feature was added.** Selecting a single rendered fade/transition clip and pressing delete will cause the deleted area to be covered using material from adjacent clips if such material is available. This makes working with single track transitions/fades faster. Previous behaviour can be restored using a preference option.
150
 
151
-* **Clip ends drag with Control + Right mouse.** When a move tool - <i>Insert, Overwrite or Spacer</i> - is selected clips ends can now be dragged to change clip's length. This is useful when for example a clip in a multitrack composition needs to made longer to cover a clip track below. Clips end drags perform overwrite on empty/blank regions and insert on media regions of timeline.
152
+* **Clip ends drag with Control + Right mouse.** When a move tool - <i>Insert, Overwrite or Spacer</i> - is selected clip's ends can now be dragged to change clip's length. This is useful when for example a clip in a multitrack composition needs to be made longer to cover a clip on a track below. Clips end drags perform overwrite on empty/blank regions and insert on media regions of timeline.
153
 
154
-* **Drag'n'drop overwrite action on non-V1 tracks** has been added. Dropping on track V1 works like before, but on non-V1 tracks:
155
+* **Drag'n'drop overwrite action on non-V1 tracks** has been added. Dropping clip on track V1 works like before, but on non-V1 tracks:
156
   * clip will be inserted if dropped on a clip 
157
   * clip will overwrite available blank and empty space and will perform insert for the length of media frames that would be overwritten.
158
  
159
- This makes creating multitrack compositions faster.Previous Drag'n'drop behaviour can be restored using a preference option.
160
+ This makes creating multitrack compositions faster. Previous drag'n'drop behaviour can be restored using a preference option.
161
 
162
 * **Always on audio levels display** functionality was added. Before the audio levels could only be displayd on request, but now it possible to have audio levels rendered on background and displayed as soon as they are available 
163
 
164
flowblade-1.4.tar.gz/flowblade-trunk/docs/ROADMAP.md -> flowblade-1.8.tar.gz/flowblade-trunk/docs/ROADMAP.md Changed
54
 
1
@@ -1,37 +1,33 @@
2
 # Roadmap
3
 This document gives a broad overview what's happening next in Flowblade development. For more information see open Issues on the Issues tab.
4
 
5
-*Last updated: September 13, 2015*
6
+*Last updated: Sept. 16, 2016*
7
 
8
-## Next release (1.4)
9
-*Estimated release date is November 2015.*
10
+### Next
11
 
12
-**All audio levels displayed and rendered on background process** Some users were not happy with the "display levels on request" model that we had before.
13
+**Increasing Tools Integration** Flowblade's standalone tools and  external tools like Natron will be increasingly integrated with the timeline. There are three levels of integration here, and development will go on to increase integration one level at a time:
14
+  * **Clip and Range export** For e.g. user can open a timeline clip on the G'MIC effects tool.
15
+  * **Auto-update on render completion** After having applied an effect to a timeline clip it will be automatically updated on timeline after rendering is complete.
16
+  * **Continuos synchronization** Here doing changes on timeline clips previously set as clips containing extrenal tool rendering will cause automatic re-renders. For same tools this will require additinal IPC interface that is not yet available.
17
 
18
-**Rendered fade/transition delete update** Make fades and transitions automatically do lift and cover the gap with material from source clip(s) if possible.
19
-
20
-**Clip drag-and-drop to do overwrite when clip dropped after the last clip on track** Now the user needs to move clips manually to position and often they wish to drop clip directly into certain position on timeline.
21
-
22
-**Trimming with arrow keys** In many cases this will be more a precise and relaxed way of choosing in and out frames for trims.
23
-
24
-### Coming features
25
-
26
-**Keyframe editing on the timeline** This is mainly provided for the purpose of audio mixing that can be done more naturally on the timeline. Other parameters may later be also made editable on the timeline.
27
+**Compound clips** It should possible to make selected range and the other sequences in the project available as compound clips.
28
 
29
 **Audio Scrubbing** This will make editing audio on the timeline easier.
30
 
31
-**Compositioning and masking tool** A dedicated tool for masking and simple compositioning will be provided instead of making the timeline editing more complex by adding these features as part of the main workflow.
32
-
33
 **Single filter resizing** This is a frequently asked feature.
34
 
35
 **Slowmotion forward playback for JKL scrubbing** This needs special casing to work for technical reasons, and because of that has not been added so far.
36
 
37
-**EDL Export** We need some subset of this feature, mainly to work with Blender.
38
+**Trim edit view** This may be possible with current available APIs and will be attempted.
39
+
40
+**Titler improvements** This tool has not been updated in a while should probably be moved forward.
41
 
42
-### Long term developments
43
+### Long term
44
 
45
-**GPU Rendering** MLT already contains support for GPU rendering and it has been used by Shotcut for a while, but my experience has been that it is quite unstable. It may work well with some combinations of Qt version, graphics card and drivers but other combinations may be unusably crashy. 
46
+**GPU Rendering** MLT already contains support for GPU rendering and it has been used by Shotcut for a while, but my experience has been that it is quite unstable. It may work well with some combinations of Qt version, graphics card and drivers but other combinations may be unusably crashy.
47
+
48
+**Big translations update** Translations have currently some issues that shoud all be fixed in one go, possible adding some net based translation tool to make crating translations easier at the same time.
49
 
50
 The Wayland transition should probably be completed too before this is attempted. Currently the earliest date that this will be looked at looks to be early 2017.
51
 
52
-**Webpage** The content for this mostly already exists. 
53
+
54
flowblade-1.8.tar.gz/flowblade-trunk/docs/Screenshot-1-4-dark.png Added
flowblade-1.8.tar.gz/flowblade-trunk/docs/Screenshot_Play_Pause_Preferences.png Added
flowblade-1.8.tar.gz/flowblade-trunk/docs/Screenshot_Play_Pause_button.png Added
flowblade-1.4.tar.gz/flowblade-trunk/docs/flowblade_icon_simple.svg -> flowblade-1.8.tar.gz/flowblade-trunk/docs/flowblade_icon_simple.svg Changed
68
 
1
@@ -15,7 +15,7 @@
2
    id="svg2"
3
    version="1.1"
4
    inkscape:version="0.91 r13725"
5
-   sodipodi:docname="flowicon_2.svg"
6
+   sodipodi:docname="flowblade_icon_simple.svg"
7
    inkscape:export-filename="/home/janne/codes/docs/Flowblade/art/Flowbladebig.png"
8
    inkscape:export-xdpi="421.875"
9
    inkscape:export-ydpi="421.875">
10
@@ -32,22 +32,6 @@
11
          offset="1"
12
          id="stop5283" />
13
     </linearGradient>
14
-    <pattern
15
-       inkscape:stockid="Sand (bitmap)"
16
-       id="sand_bitmap"
17
-       height="256"
18
-       width="256"
19
-       patternUnits="userSpaceOnUse">
20
-      <!-- Seamless texture provided by FreeSeamlessTextures.com -->
21
-      <!-- License: creative commons attribution -->
22
-      <image
23
-         xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQIAIwAjAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAEEAQQDASIA AhEBAxEB/8QAHQAAAgIDAQEBAAAAAAAAAAAABgcFCAADBAkBAv/EAEIQAAICAAUDBAECBAQFAwEI AwUGBAcBAwgVFgAXJQIRFCYnITUYJDZFEzE3RgkSQVVWKFF1ZTQ4R1dhZmd2hYaV/8QAGQEAAgMB AAAAAAAAAAAAAAAAAgMAAQQF/8QAOxEAAgIBAwMDBAEBBgUDBQEAAQIDERIEEyEAIjEjMkEUQlFh M0MFJFJicYE0U5GhsRVjcnOCwtHh8P/aAAwDAQACEQMRAD8Ar2yC6nrRLre36+zv8FjfJLYn0bZB gQtC2h3u4oHp+yKrW0NbD2BMsbb3w64E0YW+XkMeAhurjgABgAqKg8D+wPiSrpH8dDjAu7T5aNj0 2SsC7aXa4dIVPT9c2MJPRa3wZBEy1IVJQAyq2sEECns9ls+KN9Jdqv2Bgfl9gAfowVFHg6/gWo1U jP03kqf4TW7CYVbOcPmuSxLKK/H62+HW6fLHh1RDH74h2Z3kF+7xvlXI/aIAA58f8+Hwrcp9cviv e5eVVtJu6SSiMCS7I9esn8L6QUKGGD7gnsj5+OD2n9tOLdQE1dXZqzOOwSrjlugD5/nwDz4yRyYT GWZ2dIzIkkfpSNAtbIViXwu3s0w8cfmRLG7wPGmCPNGS2WW45He/gY320LNfnp5J490gZeTm1LDC UPYKGky9N92WQY4HbTQ721qgMOC1zCGnuBCZ8Cj9Q/A+CoaHtn4u4OAPeAAMG/4vi7NM9H5VoJ+o e30rsPlWo2sJAxhIiB2hN55FMEIb5ChrYcc4QVKwIFqJ7N4sZwfm1oo/gPAY8B6WNT2YDr65DJmv baJZzkHq7s+BsIephyh/s3aHdBwcEOGHtRgmHOHwJ3BidNtAwYj9rkkF5/3+/dSNZ0W0XJID1LX1 V0m+SnugYkgAh1OwmHIUXlRf5wzqEtSyEMehqtD3BWjwyLPZtXZhjw7BLR/6H+fnj/UncR4zxzOr yo6ahDD2LAcNwpIztHNXGQfTnHtqsj1IizrLpp4FKRPC8WdHHh8wCoSVMqUkxyJddwahSUjq9fz6 fmD7frGNTK27RrNkaM7lresnxyQ7BfAMMgYmCE9kUB2+VKPfIKejPKur8m4T+/7+A+g4b/2HEdwz bMvJzxuC/kOlgNXJA8lWVftn8NJRhsaKYH2TW91mA8xh/kB6lY0zc1doJowM1VxsHx8Agn+A8B6Y T44ajHyv63zWjPsh8UgLIJTlUbIrKbV1XsLSBQx0NDW4b5Mr9wg8/nnENmRigp5RvzYk7B+Xd/8A Pr/ZUczLV6farQgVLV3zzD/YVHuAH5aeBKCYoFwXjN8J/wAOtyDh7kFKCtoyNyizBm9hQlqVDbqC ffj+D9ifYRKqxsxf1JFTCNMkjv70yYyLIPtaSSWucQOco6wH04Ux2kdmkZspJKwAV8QkQx5oxxJd nLLiuOp7QU3dXsIC2vhK7LGsI3dzxppPWwwh7uKUNbUWYQXLIZHD8f8AB21fbVXjTM0CxiMDdnc0 DAP1B1FwHYH7AqrM5qFTazG2Dm1utmFxxN3dHtS2k/uR257N1KH+GHrdDwQ+SHK07lnLgwWSlNsw xHpMI7bAA5/ivnz6Cgit4PBCwcwzb4HFbs5oW5K9dDsBaFOq3yLXtc02yVet1Wt2oH4+Ham1gAg3 BZrN83TY7RduDoPPsP3/AKgbwHslg2o1WqGuZAW4tqNpap2qZHbA+nOVLVzwevw7IH1IB6THGEdD r89Bhi3loFE2b97w597f54ABkkZpSxZ33akJL5xo7UHijehnhxk2KXa0oHUiXEMmSJg5S0jrOseS MzVX4s0CeeoEdl1PKrMwBynBtGq5KNp7IDcn4nxQPfgWyEE+G+La2tkDBzkEBHrf2ab4Gk0c27c4 2B+QQHn0HrdYGXDq+4JkCxk82H7wVLYKuSiODuYV1evHxoodgZEMPzx9HmAf7HtgxDFszNwnm14f rv8AwFBwAdiu6B3wxUsAo1v82xnxkd2gOnj69Q1eLLPSltgrdP8Ah2oyD2SuQJHvgYWVkXxnfAjt SZz9/wD7BhPtge6FwpdibVWcNVQyS2ryPDcVdshlJbDXJ5bsCtzEwNMD1/g842fbUEwzoyu0LNQH OEuxzgOwAP39gaiuVRvObqlVhqIroX92GX45yI8iupuJK0jOMcc6F3e2I7+B7sgP145vhg0vV9d2 WLtoW0WTGVK5yadbHCt3YwvMmnypbC7Sp6/al2p4dDtSv1uCeYENGuAn7/ZvdISQZ/8Ar4+AAPy/ WlPeE/tWktr5Dwo1Xs5tlh0myLYqdkKUjYe1w18OyPlDhw49bnNqfPgzMVkoLZif9bdogB/wGL97 2ET2tkr6liWUGuAlErSwgktgtSq3BeMNCuvFLkW8A8yGyQ1tPZEcC49udsRilojNjCJO+cBQff36 XinDqsWYcE0XqEbZlXje08hquaSWMNErTgh1fMIQ/eYt/wA4jtrABBzNsw4KT9tkeMGA+A+/e3Sr fZlWR8N2Z2QKM5HjGGLxpa5XZyGQxAXk3wJKrTRrde4k4ovtrN6OF0a7TZDfjqxcN0cBeY4bNVZJ PMmG22VdPyR9hTAKawlbGhjzCG4B/r7JBn19WjUYt+31dX7QdkzZvYN/4DboDgICqINstBI07V7R YauCcO6Upttgw1NTxZr5LQ0jfoZCG+TIemPh8PssngZ3BsWho5zvfCd/2Df9/PoPR5UavX4GPk2X aF5OyHdwdlE1+yDWBecKv5YeoeGwGFswYmMmzg59X74H4wLaBjNvdXeA2AAf8Bh1DvkiWkPhJNgV KbsKkYcnlFe2E4cbq8WWF/DYFtwfFuGtjzEFtsDEGyowx8fBhPukE2NB/fwADwBQiNZsCHldKdlR L2a8TGmOWFmk4ys9w4JGTcC9vYknGfnNODImPGN2vNn/AEPQ2tslfxYeynrU7M1yHpynHiHnV+Jm AXxIcnKq0+h32Yth2S0DDUer/UPVbJ9oVyZM4k1cEOIP0FB6YTQv2AMtQbWmqB2W3y7qZGlmB2hj 9XbKAV2FolIfez5kNwTx4Z4Pd6fhjHmr/wBN8Cef7RH9/AbAAG6PpNDqWHXzGr2Rv2lWpZLZHhu1 gpNb20m0NY1jJ5Awth3DkifDOHSLbO2ysyqv2ztRJSTZzE/v+H0E+AUuWhpaQhmEdoT7kJKSQt6h cENPYJaHYybXt2lDCeYQw9Vw09gW2rtf9wxJvnGWZ4CBDZz8Rffl9+9xZZvQGSN6KRbkMe3/ADVw kubZxjD1YsFzJQZKOiiZMpW2nGb508255+B6aVVcnnK/iuQO/JmXXLBMqWK1O0ym3xtr1f43J+GL tpI37j7JiyGOz5AxOn8ReDAwntiy8nMceD8AP7/+/gPWLUhYF6Wqhn59yEhum+6XwIWRzFhVRU8P a7DpF8qusA9bvkO+GRg3zj7Y1J9G4WgLrMm8GwiSbt0BsHXnvlo4sWLGvltKpJPSGRkYa335IU0/ dKyFvhjjbhM09hzKcHBnmACD3Pa3wmso/m3jf+AoJ/gL8feUxHvTTwLuyVPh/MrkapS7A+GwMK2B 0+yxbQH5gZW5gfvAHrqfZ75R4cmzfrWe9u3B+AgH7+wdNYRNOuWazKiOGKemmdCo3y9S8O44pjxw cuGCN49MxkCHTtMquQ9yK+nrNWjx9GRTKu1Jk9W3b0jUNluNIq8bX2oIlaIEytqVhI9e2pR9mmKv PKcpo4/MMB5kOaQmc834J+vA/BpN2BHgAffQB9+QOp4oUj0YMsg9TZi4zGahu9hMCHnGOz55o2H5 jBMMGXxDmYMiq+bBOT3ni7R+KrR2Q6APoP8ApFsB88F6mL007tFJ2rX1nUBarbZC2kMHCCC8HsZX lyhcNwqtDhvictr6fOQ7QAo75xlpQ6z/AN7Y7/sB/wDz60ttmB3JH1gdy9MbYq3S7JK9H0+NSfw8 XKpGUh2QwTHx8oeq09ghzuH8H/GaHaKMMOOxsJsIDYAFRPp/pChhcLwu2mkqZpz/AHlGMldsZqL2 VbHnIMOFx5Esx3HSVI3VyilPRAxxs1353YIHGNfdn2myX3MsuYBtqwdS1tZKk4VdWUdkGuESq5V8 WEeiGNQOzmEOqzFfrYLVLcAF5sgmTfFcY9PARJpN43+3fP8AAUEAEx3BPA2w4ZtjGKUtUMt+Yzv4 d7N4ueiK8rbw74HreyE/S+HVW2r1Kuds4GLrMmDq7TxSfPwL9h7c+2CHTx5SkZie25q2pMunit5K 6QW3ZgiLcUDwMpW7A4B63T3xDYJqqPcLLo9bWRnKNs3s39+7ur9uH6i6gSC3Nrlwya0qAPvAFlUb CHt5KSkTItjCRcWyOYLbI4Vut2An8Dx5wYRka0GgmMtTtd/UAD8uoIDpjIsb4Rj21hH+bCk936of B8/A6EllfdkXEGtxiadaxxzjo4/IXuN0R5HMjiVoeVUbqrW0cOAldEsji1TE15TY2ipbtsa2rHAO L4iRLg4enU9t9aHTAu3iiH6VgJi7JWL93e386voTBh9rOswi5mKulB8ZCQF3yalsJHJXXcDuhyUM tbabzBbrdbW7HDp5gGpJ9DQbIRlm0Gjc3h25vh+In4AA5AwPx2n12LMolzGD2oNSZM2JFr2oD+l5 fYb4PXGw2PEQ0/jWpun6TxtHlaliQgw1pnFlBeB3wYK3vdCfULYAAA31UTNN9l13Q4YVTJvSvArF JXmhqZLAsyIrnrY1BRa3p8PD+uQ8bI8edBQyaxuhPfDlouxz9UH9T58+vezkQEOoe2jCLubchx3X Pct7tpwcccPLX014dtCytSTHT1A4IvTvnsbsd+FqTDuN5MOCOUpRZ05WlgWQ7VeyaqtOua1Dl+Oy LbgVDi3N4PU5MToQeZauKGPZJ+kxw9sCXeQmj4PBo2EeGAAfww5Bj05cut67FWhkmRbI2u0+4alb JF2Oy/FhvltMJ60Fuv5l8GHCbD+YqvloqTUyDdQotWqAYj2ibCHOAoL9sC/z6oq6uCOU4utlHNqU oeUkxi25GK/ELdjJtgi1eH7vn5UDj1uCeHwDnaB57oDBmLtSYT9/P7Bx8/04Ed0IVBDMLcXFJsIp T5PvQNr3UAWfGgX8qKYT9ntStoagw+/IENV2ys3wqzDHje0r8RYH/wDPfykTBvqIoc3aERuzSxK7 SJjsyu8rx54ZSYoq8ZG2Fi1xFmRFdqTTupWT/lxsfVjq+d7FO+xjt+1i3QfeFgR7Lp92cldJpOsW hVUkghXqewLy3UqGkWNXKHaD7MhuFwPjBvkBvtqufvKvpfZyYPuib7uvz99+Ae2EbHq900tOFb02 m2ENfNZFesvdAC+acGxbu2kXer7Qocjg3iE9bmVhyqfYCmcMExhRDZkY4lG9O5xg8+AxAb+vs5sH j6zMMsqoLCNpGbDGlk+zlWQpvkWXE5QtuCe4Mi2yWoP7cttfvuzsxMWhjN8wxCHACDz5A9z/AEEr dLlKWsTm9VLdAh81bpxIR7OQ1eWYixWza2Rfh42mHZa2HrgJtHwHhkWUYoLRmZ4NpOx8+38+AQd/ 6IPI6RkN2cYs49c5SwRneW+Mdy055AYcXYopGSpZbmW9wg5RtYXHF6GVU2XaKNddjhMT8qQ7QMrO jW07PjJ/D81YUOwuEoW2AXxbr9cMUPD2ZwZAc9QPPBgmMaGju+j/AIu2AB9/P/5klgLY8pHpOxtO VzWRdkUxUrYv8kYK9cO16QU+YRw7Vw0O4GBkBgbgrSBtgzjHnEn/AH8fQfP+fFcyyHQoCW3fNGjY dLB6KU0d2Q4zEtgUNhPckT09kDmGSYQhwUOBdNOrayMF+TBmzfBz78/7AggH7qNtyGKDVgHbRfCZ koxJ2/t68WE4Jp6srGFbfMDLdwODJxvgbA+KvBhlXlHjg/NgiOg/2AAg4dCgYbOYxdclwuwkYMZj S6F491mhd+BXRllZJokjedJMDnGZQ7Sc5usMcseWfbwznDEAGyemdWdgXZfqFZyYLJEgKaZNqa/a j5S9I92k1dqXT6h7Ot6kDD4nv6HO7Pnwd2M3dCh0ZZB2jVxtH2DgP+rwDpbslgQ01Hh90M6SNQw5 uXGJO1f2a4yrG1Hi651UJ9kTLIMUPw+yUdD5aDW1lmKU2zM29hODn18Bbp9+Xz9RdM7vAUsGo74d wN8EtJZQ9TjCwWcyVf5Qo7vlXw19bMUPMT0PkgNDYLaCGOTq6vWfhDfB7dPn9/8APH+g/T22QndH zmPKrHTwNimI13UuTDv68yASl86c7k7X2Qh3wnvhghMgwLAnI4e8llXtAnb7xaPNnjYOP+3uA6WF iYxSO2yiTRh4YJbj08nOSBcVv454LUTXVqrs0q3DJhC/v5L5BP8Ahx/Vw/kn5XbiV5e7HA2201aH KP1B13i9hEVusAPukfIHOXob9LdT8gjm1haevVOyAls+h3tA2Fxz3DOyk9pdTeTLJo+Wsxl5fVEg erLAnOvJ6yb0qfS+2zquZNEesPH0D8mJkhCFK3RJTUctAWI/orkrLjLPrppuhBJcRxR2kL6xIkt8 MRDFQREjJxMQCkqVnTcP7Zv0dUTFfpnb8paYn+T5FH//AHCB/wCntTNpA7MAzPvAZE0S1bTVZ5qz XH46v/IOXJY2n/Jsu7uNzJdkJLvAJB2C2DFS6lsbGPLY8PMD7w4ckrn+QnLZO8vxmM+7O6Mfxt3D wAAAfh08XXenO42pDMp5KHV7GMuORtshTmCxaQrvie4B+YXYHW17lVSEKleHCoFl8VyaMd4T7oP3 5B+/AOgnTm65+pDBlGQaNCF7fagktHSaxq+vocpWuJyil7AMfqtslgf0+pVXxn33NmvBJ2TgNu4v 2GCDwEAzrMX1tjOElJu063Gt5qqbYav1FTLAXocopyiua343DMPt2ByF2I8C0La3gZxfbCXhEmqz 58BbvALdQUEBUcuw2AbJBStJ7dtFI20xtsqt+7JQfxfPTZAsrZOUzPuZzFHlyoFCKFLrm8i1XQqz 0pQ7RmTx5KyzNYxhtq5CS77xnSKnmOUVhq8qhjoaHMhp/MFqch3BWn+r7RyYnwnHEHsAA+wYn/AB NgENVGkGxDFQJrhUqemklKwqvaj2n8sngebq9y4L4e1HAPZEPEPg2/AanzxYt5Wfwm7gwH34B+p7 p2VnD0xuSmSsbW5cBvODV7Vzu0Lcyhy3PHKwjtSp4+kmRDfHzAgycD+f2rWSenOryfBki0cTn0F+ 8+fAdLF4qcO5UuhhothMjVFmG4iQHQ1+pw1IgZaHY1PVfDcDOm8xuC21gSAGx2QZWZRXJ/hM27Az /gMPbDf4TFqJHV88FxbF0ygeQcRuDb6bUbVPa1JgH8rl3LIljQIpT1EQuA9yKjcNHImIwy4IbJrx bjt6cwcWjz8tb0yMeopSZDJIap59zXK47xF0+1kBQ6rX63qtat8xZDBMOcwUoKG8jNrRmZHCbJ5/ H3Pn18/0bKcNkXKztruNnMlDq+TGs14GgKfiBz0V3lFHDmFV0myzK3X/AOQX6WnMhNGFFLfZnh2N 8H8BwE+hYoOKTrdoFmcvSjXJqhwlnZVb3HbKdDqZf+GBlXyLtB8ILb5ySaHXw+/OEA4h8ZuRXZsT nhAQDgGP/tAkCHKGRWq8oSQLgPXBJs1HMKyOXuADKpwor8gmLYeZVfMA9V2XaCiq7YzK4vcznCP7 /wDQfsHUKyoxkUueWLq8eAZxLJE7juf3bSnGuzgW3npjd4RWZGdaBdGytGigkjQrQrb3WUNkc/NL 46MI/r02LhSYGaKxtG7AS0g2EjkgKfDmoloMVilFt/2gPM/o6dArCfgyIwspj9485jv/AB/2PIOw LEfMrhIvtVi6lWWKA0tO0WLX11uOm+Hv8qIB4GPMJzInoUvFjtTGrp8JPw3R8eRrwb3s5z73wfvZ BQGcjnHhjRwLu+DY1zJqGSLcwAsEQOmxZe/B0CWYcDDg4OAb8gHoEMYsq6HUDMbdqudvv4DYAKCf 3+SX8ul4tNnlxDrFkfLWMakIjQYabf8AmW0BU0NDMMENwreYYT+HNW3zwkPbOLvIwG7Wib3/AH8+ AqLYNgZIGyXMYuXRGS7MM4oA5UMtuyapcshytcrWO40IMKotyq1bW5tYErVt/iHcCasGjYpA6dw8 NNtTO08VUk6S7CynYavK4G4Lw2c9pzXmj5hAO4WRMD2RX8ycpOCGD7ZvO1rLz92NgwP7/v8AiA67 I4exCinXwHNrfHOnzLRthH/iQ5EYrm5buuQCyL62HDmJgcehtXD/AJyGsvNXtAsYDCJJsGA38/yD f+iSyEev6rR85jF8bVQIEYWIHocdehNB4SB2cgY5JDZP9hsGMGYsjFcoTJ7IEdgePgNg+g9btRGY lUEYfGiy7ySUnvkbEmM49V7CyPlSlsPh08tuC2hmFtPwR+4Flg2TFmKFGZGBhEk3+rB/QP36CWJg KCNjUsSxLUk20FyVYlLyN7l5RXwsWORZRoVjAt2co6Or7T4Z4UQZYn80bAC2ByTQpnMjwr1e2Zyl cjh2lrSt+3oewnCt9PcOVbS9XMWt+BsheZNh7xBn2gBeIaysvgsmNeDZsI8c+fgHH6i+/Nogl1/l Ph5XSLsJVlWo0aw2hYTJZ9OWm4i9PbRFZON1At2oYhj1tV7wXS7w1nlO2M6OkpJvf+PnvvwDB+Rl 6ahUOeQSQxrJbXxSybRikFXOMKYZ8sa4wJ64CFjrZgxxBP2NuvA9XMxGWVf6Mc4TV3d0AAP7+eAd RxBsR858uCvmi5kCyKMmDYkfOtSp6cMVKeYXIAtuLJ2HhmE/h7U2p7bs/JnxXsz97uyj9/fwHsAw Pvyw8jGKaUppnLrJsyGKWOSMUELbkLZZc0AFx8HPIYtYxI0mJ3Yo8VacDbkSQ3kiG3xAsWec+3ha 5D1Or19ysysoCkhxrzsF2By2B8oHUBYU0XKrIAmrZ8PcFbuDInjw6PuGxoYx55Rxg4bCef8AAAN/ 2DpnVm8r6bl2ohnmq2nZoGxrCHB2m6F6YLFrwGJ/qQth6T+yAwNwfT+M2gU4Nwm0fff8F8ByA/j0 BtCG+Ntf39muSqNrEeq21YY8ZMES1ooeLXKLDj63MGE98W09k/iHT60tSHwZDwGLPNvZ44D/ANNg 6YVTvmYhsA5IV7ISSVl6b1thYK9pNfEoYsp/FA5cfpMOyMoeyKfT1V8r9Sag7NzxXGW/+E9PDxyB Aft/oTrKyTSNMhl3UEixyfUNFBq0khmhkZS0EKRp7QtiIWWuu0Dq4pY0k0yg7GoO40eQyj2zhTvJ xhn8DBvBs8X1Xts4X8gwuHsmyE9ymRZa/wDkCIyxVdhioYf8VOHzC7hDBvn9SkyfFyfOHbzj+AAA AB/FBP4RpgHYgZTD1ouX8bPZR64xP4YD16txT6RaBSGv44uCfDmEFu1FK8PnBxgxDwWd8STZs4AA fofft/xajAnuGUtsosDMk1jmgSVZODhalkO8zGm6nPRQ6+yU/DuDZ8Pg1L5x8J1nTbQU2PZTZx+Q f9v7/wBYvmKvcmDOgT6TNh9hCe1YnzDDMsY8WAlA/A29Dh6kIY+Z8/YYVb/tYyoObf2DYMcP3/oA MInJd3vCszeNEeP9b5/0H46zgBJQYEeTxhmu1uUVuuXqqF+eW6W6uDsjNKJ567r+si1BlnfET3wC rsM1XfBIt8ML8xbmODIYHzIMDfmoPwa5GjnJw2Edjn7Bz4Av9G18DylQZk2udSVSv1Y6h1UJbFoM mTqQdw7ketgC5QuHrnau4FtfMI54gBOe35QRkY47OwR44CfAfQefdJ9beFe6Y/xbBtR2uCLW62JX jK3W9OODRUrYrtDJX+K3T9cMifTzhcVD4tqPhudotCMz72b4OfQWA/4BBP8AVtK/W83WRYiSuWrD k2dzBkr1w7Vp9sPpRoE1fEMsG8LbJaj5YMz8gNqP7LOkt8eiYPezewoPIEF+PgH4/nlbZ1MItI6h T3viIOfApTuZ/rbxKA2xYU+NdzTBkkzmkl7gq5benNf8Qchs7XO3794M9bW3TqRDtHMDK6fxKwhp iVMk0jHMODhWXxXzT0UlmE9kMfRFtgtQ4Ar/AAOLaz/QxM5aJz/rwHfz/RWPsRLgC0OekGFLN+GS Ex0nJX1SZKV+ecksBbMGJnJB8ztKQxnY/wBL4+wRJCc+X9//AH8/i2tRFTzIpRPuQMkyQKbqQQLY tCjT1oO6HKi6j6vVw/MA5hbMJ7AhtSHcE+j5iMM9mZmBm/B7+ggH4Bz7gNS8swwWMyh9hDxmqA4E hK+tskgsYltFTi32HX4cwHcNnX2Q5ZY9S7kYVA0WgMWcPOHAGwcBPgOfH9ajCIXKjIeWdztlMaoV 3ZlrPytUPNmkMuUh7Nu3jTzleZIy8L4rx8/kddhiRlhqPmFA1kBEl3p/VFp7q8PeVgr0O+IqnQ5T cHBDZFvSXNT2TYWAC87YivlojBmx9kzgGogHd1Bfv1uAvj5ikh3NaCuh0mngdaS3E0j39WNr/MlR S13K7gwWRDZNGaeh/MVe0ClBsgmTV0OzMEc3slHnwFu7A/AMMX6tLYplHx0W7MfUNSas6n5Kmrw1 tHpxDq+xnem4u4WQH5gtwqv2OBV4EHgMWSj4zLPNv38/sAA+Aw388rPLmGWDOMgpkkxZeTGsK2AO lZGYWSxtQS9UrkHsBwMJ+oS1Fth7qT3Ch1X/AFkKLX5swdjiCAP0G/Px4+f6zPzgU8QsuEX/ALik GWPP/L2U2POQ7QfLAhXtzzfhiuOOMbUI3Js3uU5K0McCbOVCuk0owafj9M2/VTI2nnEmbiSKOfGC WHqYo27FMYPmU8n2pjX4exq0wUmpbJ4XIrswwHVxvfD4B/fgADYOnmlnA554t88BZKufLLslliL9 kV6Q+YKcpcWVZFH8DMGFtbT2SnSDABeO7+6Pmnonwn7wAPnz6CggPY+kzjYltrINAudejbgxcJLu 8WpW7REcHyLLaKvDsBiYYhsjJiyPF8WBdMFkp/gdoVnZjxvf9ffQaiAcBAM6HHdbW1GUnedyO1kW RKmVukB2TJr9hre0NX1ZSqvQ2APMcLgquYApPYWDfFsmUQnxm/e6ueP07unkAAfwkm4rZsqSIIcc 5FDSbkZBjRmsZbtvRoFMDw+XbI/bgO50mDrGvMksE9XKi/O3tcpfOY7l+W1Dpc4Gp+YBgQ1Jb2F/ YTBh2V+SASks8VDj5jJMp+GHIBziH8DttZizfDQTszCrrROe3u/VEfPgN/WItfMNpXBcigXZ8uQC ciMFbpIfH+IJpLIcXTen3BQ62HT3xfhnJ/LUfc9raLMeXhJ2MHUXd3nx/YAPXyY8UfZZBJFrmmNs yW1krdgre4KH0360bIlXJqEKWMn19D2iZMshPToL5YPzpjMs2gh0b7nAdXeAfj/aLgL91vAMmZPY KrPFOfrcC8m3Z4fH2yHV9jcxfHxxMcwmXCHIIc5CsCBzDbCgu31mq0jfAZ9+Pvz8A2BB6FJu0sXT BnZ2Ltt4WFYgDFsqjWR77eIwtd1ibH7c/wDwjyq+1b7xWUjRxj/5k/bRgcy8HxcsTOzc1PWwMBDr d3jw74H8wfPiWhq04fcNV88fA6+yI8Bwn1y4MyMr/jP6TaP4i9sH73t3o8ISFNSsCt56kyVvZzQe CWFp/WzFoUjcEUp2bctwp/TGYQ5neCHA4f8AAcFmzOL8mR0lJCfr9+v1BQQCCsct0eK+pbBcDXYb p9Iyaud6/cM7hEIoBxixbUwmXByTZx5hqUbgtq1Q9QLLQ+LPOEkI7+fP/QeA9WPR63bavT2WUiZN jy1aGgiKP/4ldZF20QnOdfRIreOT5tViLsfcLTVbKQHxrMWcLVxVZowV22MFgBfqj5+/88wYAItx o9mNpZolCVtCfGKOPeVu65Jtu0grjuXdPBIrLuPp0xmn242jUk54RiVpUUih43WW7NlboeAiLdfM ypMt8aD2SNMTw6TyglW8gTMFuVhHvh4GIeoRkcIdXhwc+j324tr7yK6NZhzmzs8bAeP1G/ddlN5g +wafs5ozXy0SSiB7IsFkIdficClS6cK5aZvzKfDzE9kx4O+N55HhLJPniy8vGyJIPfz/APYAHRVe C/DMvlAy8rOqUO0IY0TR8MPbEu7GhDsIWBZHAPdkOGtsi/DtTS0PgTkOzLfvhD2zZKu4OfAPz8fP /QcVuLS7QVzDsrq+ck5NI2EaLI8wbHs1DKIbFFrkyv8AbdDZEIPYAejzw89Orfa6HF4fSgmLyfwQ d/3/AOglIQVXEZPG6bgaffkiJ9s7yYJlt0cUwXMvea49xRbaSVMHEMiNjmuP1GJW4PJwzyW37wtD ta7E8YyEuvnyvA6Qt6b7PqAbSaQYr0bYBbgYFsKWzg48wmB3Cn0+ZBgD1JHmLIx8F2YzbIE4PsB/ wHQdcOoSr1ep85yMtVtGMnJUl6tyWm9opzdBbZFKsg/Z09kTw6/24ocgpKq2TswW0VmsnEg2E58A Qfvx9+6NylmSOcLZnngQO714S4/TLUvxPigV9XFh0+Y+Qw8wPPMQVJwQzkNG4GLGI2CTaJs6AX35 BP7Bz7qXswWr/SWNcT1KG5Z1S1kj2cq4RKrTalYXKL3QmB/hp/zw4OfR74DT1nDdHkYDwdt8/VCP PwHwAxKzmKOplaSyBDzlJce47DjHLtoc/PP4Sz9uatCESs2mF1kQVxH+xy58gf6G4tCHdVtlVmBs Y/N0y4MjvlZZtngapbR1yoNrC2TLiRBB2PPF6eSUqsyWROJC5B2eegerKKEWkuy4GcjKnR/X6es6 8kJ1rNtuRxjOM08R84lFyCgVlm1HDBq6lPJw2Y/JDZ+QGbnHNn5WGSjzlGAJlwXu2hBRWhLxSBYP qwmZqanZ0mpU7Y9WFRTSrtA4qCtC93mgKv55NeAdZmY8kgk+SYtLyfz/AMN1ZMeLW4FBuE9DcIyS GfLIEtGdpXpewnxypGIBpIxaCe4TLVfA48PqaQ6/rQHZFZExf5MBhHak3hBfkDfwPgEHI9b3QUS2 qK7mLAWyieRR3gbW6fbBjs3ccqUtkA8xktStw9oTAdZuEGCHRkWrydGswP8AfQHnwHAQHRfMy0My vuB6Lk3Yk5W9ltPFnTB8uHFsZIlKz4whw6fcENkcK3VZ4+BBMDGb+HNmZgenjZEffz+PID/sfiO7 FsK6OSeLBmX9qEY+f2F9qTxKEBA6mrGlGOYzKrsiGYT4femv9PEHAnb/ALVn/mk/iI/QaCAQe7vR XE2ZGBeEqZXd8M447vSgYsO2/wCWz5Hp9AQyBTltI3cErL1O3ccmx7+ztrgA8m+km4Q63bY5i2q+ zjdqSiSkJz7ITh7DMFvlZOQF8XzDIIZJgerw6rZa/Pp1xWRhRoJ7FzZ23/YOfH9/AdWVzGB8yWCk zS5Sem8lXzsk2wYo3RzV+zi6vbCib+NodkakJgdewggbAun5gxmQxfJgfhP3/FfP7AA6X2ZT7o5O hK2haeEmUjkkohgC1VvEMFJTDXJ4wQZYeNkQ4ZDZAKepI6eTrPTm+DEZHScUk4AxPvx8/iAx6Go6 XADD69Pcqf63zUKyCo9qzk9TmFLaSGiUn/MMcbQ0PeIPb898ys/obMTB4fR2D/Lz+waGETqVY3dc 3KtDi/4pY7ux7rqjVc2tJHVg2LivhWi5uvO7BL4vigPDXfFFYeGD3BPQ8pqvVJrR2shhDmLDDr0M qB7ccbcIdwuC3qEZGAOqwLQUp3BnkorrOHCfNn9/58/H+rUOgekzLrf0Btu1bs4KyDayX6ruCwVO H8oTLV63+yWQyXWn8wONq/AajCNUCsLWVl41D+cqLz/aIB4CompRsuwyDoehymctgU3TG7fIr3Tq oJAerxbZXMqGPiTHAxMcCE14xX7MVZjNWYsWzb4E5th9+xwx2Drkr9gq8DX9evgsbW9wW0HNtkdJ GOFezGimxMUX3QMMlD3AhsjhVbU+484MVmjd0OcvATGk+AoP9gAAD65A9xymTCZ3RIVxyPEsMjEm x8RqpFeGv7aJQLbyghMI0zZ3kwqqIAXFrysgmxQHg5cHYc4pq/8AguVhIbIHu7OQKyDwya+77DfC 9qClOC+Hp+ZMhmCK21QLQQzhhGJvmLzwZ19rUftgP9osMD7882B0fTzRXuXQUyNpjbUmtxK/QIGj 6yhORR3vipcPhWo+PkNDIfA3CpUdbZqgFq7MtPBu7KuOPwB/YP8Av1J5hxbMx1VSrkC716m2QybO YqtXXocqxncC5B2CyLIhh6rDpyHVdl0fypPrPa6v8G7BEkGe8+fQd/w6sIDqqt74wmVzpVv52Q7Q JRlOOnrlsVOyIQCXUotk5JM1OVvM3DtyhsCjcRgmjK5RZZvxc71XjsAA+/c+6GMCaRjJgIQh3Fke kMC0BCUrv8mnyXEn2NlQFnaM4A+2rP54U+PjxXn56rSPrMxdOZWNLAWrTNVYA+EYXjOv8gkPiaKs JDtpwX3yHDW7gZCHFXxfUp1Vk1lnaLMGA+EhLU4CfAL5/wABgVUeDH1UwZNQVfbS3bcpD08VlbF5 TE+nE+ULXgLTMHsifMxDshEOcPD1L6y8vgtZJ2p4XHE+ggD6CAxXwHG2ENSeWGzldIyX9kVxvcFw Y7rH6hK3fE3lG8WDDDuC2hw19PBttYPm8bZcm2Eke7DfOcfAANgAAMTBQfLRznt1MxdNVA2CBs6P 9qM57uhLDQpysFBfqxPtOyMETARg21fp5eGN5eMVcWsoxx2NY4nzzBgwH8McGTLKquHhfBaydGiO NmxaySRXdEDEnwbri63Mp8QwdzQVfb8i+SW45HNc31G3LTXarR+t5rS1LdnSj2oi4yA3OpdsT2gW WRBhgeY4et1XMYIc6tCNaWqyPPF0NZxqurvypv4Dz5/Hf5GlHiPbWWn1+90yNs7SNRtx05bB5IR6 9MagdT6Rp9TU+wOBob5MD/EeJ+n+lnjDg3vUBLEIDw90G+z4DkDBg/jauyWIpTD1fKSeyWQBMXqp p9S0baDY+K6bqaKNFqL6G4GdPb4hL6ej1oQn3guWYTtB8erMRwnnO0WwYANg2C0WoN4R7Ut2dFqv R2zaWFdcHRA9hBli429yiei2auLjpczC0k+nU3Cepv6krYPK20i0h6OnLsCnkL2xPr3/AC+k9HTP GGY7bruvp2hGzYIn0yTGYFilUXEUiSwyWVlRyqMKSUxK7QNjcKwSivfH5A/y+oI3+f48fnIUosgW rgVO4ANGVvJ0u1ySbVOwDFSp5aZYtXqZ60Jae+LcwOZ28xOodwgVwt/aOTc42R2R8D6CAA8B2BBd kx0sQWDG3dlWok5WoyjRtI1fUunUxDQwNnlhdoMtfp63MW5ignzEd8IWXTrIMZmi+CYyq0kJaPgP P9ot/wCmO2PkB80eDavfKfUqNt52NRLQybUX2xvlK1xi4vsn0ljMMWTaAYHQ9ovbwns4tWpp5x3t J2QCv4nkHH9T8aT0AW5pCiKzjbKSyuCxZdccnpqyKga1xntqI01g9DrtW5jHcM2e4bgfAwJpNlZx rusvNI2ilAscAGKDYHp9R48lY8lWMh49SCJZpHERzK1ubaxzSXHPa4uzLW2QEa2x0K38oZEmSRAj Ksn8U6AAEnA3tZGuBlbe3HlQENTE9crxvq/Nrak4QGY7cvSbCjl4h4ovW1Q4deZGTtY30mvslxcP 1D8b3MoUJjARsJqHtTYPPgOQbDO1ePIE7HSRgejQudPve7FPGztMbRcbihppbfjA+ZwMOYDD4gSt SBCCY+hlMBZw2E4O/AD4ABwHnwBt/wAvPOJ+VqWarspN3DrYmwE+ZU+0Ve5aj6HKPo8xMhwoafzz YSCic5yTV2jjPCTbt4AAfAHz/sAD1s+75zmZcarW1GJZ9NGlPBEMAGCZYzjYbPST4Qw41ZMIzX6e qIdn1qjGGYW03ItDDmFpG0c+/YoJ8+wc+6pNE0cWpbTqg1Ev1Goik1M0siQTvtZSlpXfZgWl9OPC GP7I1yNqXVkarSjVTTbUTxxvtLQOlA7laj9tqAeSQTwK67HCHqEUqTvJ7UodJ1LWjs22FondtOod gQz0S2MBbh3gmWphZMwgHeMWECDh4oz4TrPEGFdjX5eqMAA5BhiAraEufVHTFf2/jU1MqSHF1Aqb agNxIcqRE1yhxhb0St4xMqwPMYFtqguFaNAhn3S0Mec4cJOIOIDDkCAgYn7bOCep2W+GMLLo1SL6 lodo3JIs5bj6cA9S2Mwpr7M7wOC3ZEOZ/qWPgQXwozK/GRlV6h+yZxBfvAn8d/6SdT6sMzKvit0N SQ7ImVfahGJGyarV2FwV7lbAIGGPD2QtsiEtp5jtLaAH/a7RUBPhLsk+A9z/AD4+fxasEj6aWPWF NZLLM8gjSM6fCNscYSwebIrzTkLd8qPmF4vqc9I4iT6ZIFYyfUgyKe+asYsMu2k7uReXXHX1V0nZ dVp9NvmnuSki4d6iXCwtVA9s7xtFTq4tPcHCZvFJp6+YeDw+eccBnKOTb4EpL2P7+fAcB3/okODz IZLW5TvWMka5NSAkV/UrsrsKELq/fkN8IVBdmFkIfH2TlvwGpPWeLPgwZiku3n8f+wYdWEMNF8tG WeumuUMJScCq7jqdomB5FDbWBsLVABML+EQxDT2T+RfHC2gfBhgtXRlne/8AfwAAgr+GB/GqNsPk htOMjRYMw2eu4PJd7YuDOYFMxsJZxV7UITHCZZC24D5jxWlP7GycG7N7mj8IN4/X/wCvz770VNIC UzTT8Nw+EiyNWbyR4mtwBcRkaxayfijIB6mffJiCcfCRRwxxoRZ9uLG75DEV22ZjuAPzQ55SSK9q UPmp5KvSFbrZmWYaHK44oGGQDsj5vCGPT0fVLYCHOmclFtJTY3Z2SQgBBwQd/wDPgONYsBsgWwhn kOwthUgMmpzLtnBmDsjKpx8aMSCfDRLguyZw9WA474yM3eQVwXhKSk2p2i594DYEEwZDhyxl8+7q 4EIhvhhtiWQ4DZDEHigflFGRfT3CZMod8YN8bavgQa3GDOL9zAZtJdjqDgfP7B4DpbuDAr5MwPaE rO7MLjIyO4dPMVfLDvivQ2oupXz5gdb+Fe9oPnuQfDieM/oZGqt2djeL8B/Xn2wPyWCvE0YN5oUQ 1yJ2w2SBf6f5HPF9MUSBkmkgfA6lY3KHOkUUytQXiW1IP24eG6mEchT6SYW6WMqq3nRckbcYeHYS +7p4uVMlcDYIa2GlzGRgZK5Uk9DtTAYMKFKzqAH+LjgDHfvAAF/okruQ+IcxqbaMSSVBZo1tYaXy FuOkJ4torI9XLJ98/h7ZDC+n3EetFDeGSzKzabk4ycq4IEOHwFugcai7Q1F0VZY/UQZxdgO5VKqt Fbu/cGZnr6R8W0WwCLMMC3ZC3ZEO4CEzftH9SzjFmE1fTm8oyObSTfAe7tRffgHPljvi2BVxuVAZ LIsKxqrCL2ke1EOv0lwKFNQm1h2C4NPeoSk64W3BkOHq/padW6z344NZnNjYPz/AUHwHP42ZVkaP ccuyILA5TGzeLechxX7s3wsLHGwl9loj9vEgLqe1JL7K+Tg2XHiuTCpDlXhnACm5tP3ZDulJ5DcA eGwLy2etF3rkWyL8Ot6gpO1E+wYcG27QbVV8ZifPFmoAfNucH8EEBbp+okJC6FbsyuzZCZ/inpIE Dakn5DXTPHlsC+MLQr9r0OGh1u+ByFko8/VhUv1m3xZSs3kGESecW7/v5B2E+n6/sTaqyT5TvuTs BmJBZfqxbkWwyC5S+5Sgw/Cn3x8DGCExVtohQ9jbn71fuaPVwT9/QbdAH/AH56oiiGFHsh6pa3QL aq9VkxHBPDsFm88fIb4UWx8yyIa2yUO4c4AuDbO3N5q/nTz3Rq5IR9gfgHvi/dOj3GKs39RESQjv il2iQoik7fTTNqTE4Z+5suB7EpYyipxjHI2Eie0dy4nzf/Y9dlmNGoAWn21eaRhW4DTSS08WEHdq lsl3ZGgC2K75ajAycDW3x8p+YcfLB+DT6MzcCJkgbsk8HYD9RH/Pv+wGtzrdXn3DOxAy6C1Q6brU JMQ7crAmMjTbSnFPIagYMGbUuFOr8RqZA4KbUYWXpn5ytdr/AGxP8CPYP6Diefp87l1vnXIBW4sO yFWtLCSXfnkwh8NotosBFzF9DZJlJmHBfWwe4AWpk7v1f3fRkc3aKSb+/IPPt/3+tNk6jK7zaTMV y+VXerJqHdm2JIdr+X3fdE1soeUtuFpp4dbxmV+H+eQQ3f6N/oactGrqu7uoIA/sCD58pAjyKCHw T3CNN1JMsKXctMXjo5pi1F1N89RJHUOM0FyYYTNh7MeZYaayc7UZ9pDGzlxZCEntp60aHr4XU1bx J9cSogesaxslhtQmr6g+eYdtkMuxw8GBbBgT55rmDGd8KVCjYpWofFIAvz9i/YAD2B7jmD0dXfGo XPJVKHbUKrpY+sLIjiXBNQ2FX4ewJ5ih4fD/ALz3Q2Nkt8YUK2ZsZs3sbBz4+fP7/wBbbGSG3Toc yhlBtFKak60PVMAfwIxBU7HlJ0y97s0+4yqGvvCrIJL1YT7eh1UtYeumSnuC9VWmfU+nwXp9Hr5B 6cO0rIsjKiW1LoK1Alkab3a9V5gqTOeBVEezDbQuk2CkmSyNmmJ/wIBGAqwnmzMH3FYBhLs4Piff kHf8T78fSS8DYRpJnMiBBJIFgXS6e8GRVQRxSNvHCNI13aNuojA6mCTK5mDnacljLFEkgknxMcbP EibpfaemZRhXC956NsyHMd9N54A2wq3pnUOq2TLXyVkEEeZYxSJKctvDhzBiWY2dHPV/Ze8syzTY v23sIEOcf2E/z5BP9VvsSu5HNFWeGrFkhq54bEvAC7D6cvloTF4DpzmVeYcLhuxPQyAcHuHwZnbN ouTznCauOVEfAL6Dv5/oqSxaW+D3XiWqhtrEoHQLZV6f4+kJ5+0LNin63T4b5SZiqw9gOCruD5Vb ITxF2g8s2yAzewfqA8BsEw2ZlfrlsKtcrg0lWFqw6TLJ9boWndefIrRqEVzyGw4ofeCZajB85D4l amGKzte5g+bG0dB2AAf2BB2AkVoGfCXJFfUuqbm5j624RdLV7wANH2XXNA5G+odpZIkjdtuxH2xn CKKMYpzj/HZ7j7iPiz0pGlQ5cYDB5pVlg1WqzDTQMmVjQ13UwwJ6CWBM5cRkLubn6mZ4m04/oy1u Iuz0r1yZBpaPVJPrdwUiMQAyQl0FnRPn0XTeoLOmn5o7ZziIcbKmYV+1adWbYsZbKIjefiZIBt9T mEmZdeERgaUJyMit1D0QlAQN+AchRfWWZDU6ZnSzqkQlDrtsqcTHshsKxGOW4thaq6Fi+BZoxp4G pm0hZjRY7nk8Wa2zV0TVmrIvmxMWSn2g7uBJDr7UUEs9kAqSQPshJX6yD1zXOsVnqVPIQ9QtwWoy OFgGLGA3A24bYstBSs8dk1e9qwGO/wCJ8AAf+kktrdmNAvOsqoHZbD1fwBhtiYeHXHZCuriRauhk ENkmYsiG4MntqAbaPcOMixaMjd0fvB9BP+3PT/VzZhA5d3YcfXJgktns52rEOxkniwTAtoLRHKGv w6HfFtwqpwQzlSkLawTybzV/JnnhKSbB/X8bdx+g1FSdkrcmBeHYDV5IlkwKfW3dPmaaZC8HtByi NAuY4GNQhit2RkX3wG2j+VJ+57WLKA3bwb8g/qA+/H7j5VlSJFhheJoi43MrsMU9m3ItDGTvqz2n oZEaAsJN4TOjpIcZYPIXE+rGM8eeF8XRI4HT4o6o1M8l17clN2QtrcpVshTq+wjFbid+tCmyltQ6 /MTHvjb4Ph3FgPQ3j3rPa/ypsmJy3eQAOA+3UCt0HZFg1fbWVAhjc5Sm/L1UW1WxBhDq8lerlXcL AW4e8WRuAdHtshS0GY8kxdy7n+oRHAAD4D9/YAClfFup814DudS2RW+oSwc4avMMyk6nsJlFykdD PUN8xPviny7gnofzyCG8YlBloVejPNqfdng/4AAf5912Ols35UFgOGUUyXZq0qnjbZU7VpqyLYfJ UVeV2lkT3AP8xkwq6H8BP74Q+75QoT93Z3q54AVEf2Dnz91ZSfHH09ReqR6kTsjgBPYEyO66fYuU ednlceVs8LMql5Yc4WiDiXKR52ruR8VEe5XctN7R3Guu2r4epSoLEh6jLL43qu08LcZTj2ENsCwl spFthDcqfHuEMxDEbhvkBg+DtjMLaCazikm+DgPPn9/2AAUg0pgXE/OtVMMVck79H7Xnlsewhygt sKWMnjzFqB1vjZAxO4fiq7mTq8oTRjmO9nAFQnwH0H9exPZMtDr8PlyYdbtSbT6kJYJhJfsKt5Vj 05cnJGCHMD2rDW18Pv4A/O4ys2gLRvN1cb98OA+f8/A0mPpOxh/yqvarafJ55Sd3AwnI7Y4VzK4u LtQ+h/khkhp8OC+ETyr72Z+TKg3pJ7qIOwAD58+wYH2FVaOQCPaQPg0atcbYlcSi0NusiSLa7BsV 1cbZOrNI8rp/Gzn+Oypah85UAeRWNc9cZxXTxZStspNmcDfM5Sd18C4fL+LEiAD62wQ7IW4c0xhz mAnocExybtezYnHdJSf6BQX7wADqefEcgLIElyfYKTYVg1XUtex6TOh4j4eV9QiuL5A497E9PZCD hOUrAPPFkEyRQoss1V7IbeAAAAfAAPAHyQOQy7GH16kJodbuCfqQJO7BUpi0Het65lbomshBjW6r MXxMX2RIPD59coawTxaPaq7R72PH7BsB/YOg/MU2QCyWdlKRiStqTUgLyvMJc3T0xyLSgMwetrcO yQ/eBw5a4PiPMWeUC0UpwnwYAAAP7+A6EsZFVEdHcWyB2MecbVi4OLeaNiu2hzz0cYVKxzFPGXwf H1Iwc4z2m8cgQ3HuJx56ZC/gDaOePm8BE8XW9FLt8O28O6GeiyyjmYHwzFkQzEP4c7j9l1yt8Z2v jO9hPPoO/nwD9j0Hg7cKdr69i20NSbCF0yEYh+SHIL1wVy0MIGMHxMVv3U5i4B/xeB5IMZygvjLw bx2NBAef6G7Yr9LgKhJt00sjIyHgKSkK7I1WAJW3w9WRSVZDAHrcOYDvlgWoqnx88GnvItXKDOcb JsZ/2P8An9g6tEQtys7VUyUBoT7srHWlMf5ceHfzBcYe0N2q+UYIJ8NDhvjgPMVy+e6rD2z7NWYJ KSTfPn5Bfv7B1meOI7U0t6nZmjQSQ930t6U6YpIPmNMQ7TWPOOA93Wjc1MMewgjiWf10h1EUS7iP WLLKkaSGgDlutLWS4YgtkjVdHzWOn4aGmgWTVFqDD2jE4rYV4WFiKoiJQ8WYPZJtJmK3fPh0eBHt 1VoaMzFKvZhndEJaOH34+/eAAdQ9ZnF9jeHxotDloF3wrYs4ab7CT14OLx7oK8NfDobhs8zZ58D4 ECH9DF1mzG+1wRH4/wABfT/n+gOv7cvyvnDUVm18qVc+VfZyTET7Oqzt6YaIpauSkxfrfklV/DcG Sd3hrTZxnA0NZJvAQIkPGP1/wCDsEwpMDopZmTLtAkEdq5qtkXh9P3YwNlkK8pIFoa38Oq6fcDEx fmQTy+PVfd5QxfGTpu0TfgPoPWponD6hZVCsXSMSXebmKKWONVoCOMbpVFybCibOVDLv20LYwtso E/ion2mycjXiq5qj1x3BQdm2NX92GagTwjIBG1uJ75WFIE1u0JrZV55Q5JEsiZvC/wBxgNoTzu5L NoXJUCz4QIc37fz/APl0pVPi+VZBJjSEM5DnocYTHSSQ93cHKVWSuUiWAYDrfciyF8ucsun1LZ8R lNFCfBzZtJB7B5/f/AXLqOzB7kvh81jhjUOvs6yBNfn3Ae2d+ANmuUXkDgYmbOyDw7VP+ecD7Zug x57XHHZ4599fPn8OhC9KyfIoOvZ+aHjKtjHiUr/Gdh8MPKKMP08hDZPmGPrcFtHz1VwGborrDMcC JP7Av/2Df7kjZiEbtw8HzlkB8cVWP5PnpQkRVDZXl8Hiqr/W7v8AXQHV7Jbjvkfjl2JZN3aVhtsG KxmWxLhtFtfFTeH9yKTquEYcDOw87gsjM8k6v2w5wlJB4PyDv5/pkMFwWYkA8m0KqcIw1jLoCQPf IcesrIsZX3W2k8gn/DcGOYwTJwFwA2NyYZ9G8J+v7/wI+/cBFQ6mj5S/kwMmseSXdDW3cPn5xCwo blXNgq7SyD4YeyOH7h3U5hsbgT4uLWSeyec/397n9gjay095ltWxnVJKJSVUqhbsHdltXiTFYWW4 uyXByQxhvFgGAbawVKqh9saVdGJ/SQgPfwGG/wD64TBRRd8UHbnV4RihGlWLxtubFjiuOScXkGCS PJRVWS7k43HBy7c+zijWI5+RDjtUCvKzMkXm1Wk5OaYCV7YKq1R5cwCULlHLh4eZzEw4J0P6eBa1 sZuvOeD/AEkHi/fv+wP3Ta1cI98C3CmVdodqupm2q9q4sHfBtHrzIeKJEXkneAO+GIcP4c5SYAIM OMehTQMeXg2b8/4FB2AAA6CDhDMqVPmBU341hRbCIiqHaklHpGGUA2FXMVPcLIZJmD5ZHzYKHX6k cMI6y+U3UAyqwuybBv4A/wDof6nVZSpVSQFGWp1AxLhPPS4dgN1tWe1ONn42DZwsLPMVWx1bjjBi 2KDUVIKHHWc0DSWAB2ws/H0+kB6fev8AFh9a4pFCK7b2zxR05xlfhbxk52qsfa+V/bjyz6fueA+i 5cmQS9uEnaWjUWc8KFt2+4dv5F6v9fKENPMu7tgN22TsAG1B8twfFd3V94X1u4Jhit3DkgKh2CpV VD3N8tBZRng2bCHH4AA2DYACD04Msu4ARd2ccmJMyvhrsp0O7/jIPKixCibDYFsut1u4B+YNR5fb VX7MLtBGGHAnvsB9+9/7BAuDorqVwQ5VfGEqyEgPJ4uhuG09r5USxxdbj+Nvi2YhuEPcP0ZCayUt DHfPu1q/l48fQcd/6O2BHrdXrsOZFvkavb9fFtSthVWzEMO0AV5Nrn6finocxk+Z8+wJ7wuEyZQX cDyjVckhAb8A/oE/gf6ilZIoRHmfqEWSEumGaWtMBkx5/Hxx+R0bLiShaMvFUTKjZ1tgAMTQrOzQ o1R5PSImCx8CHTLHXy0tzJWdGluDINYK9ZHyS2IYFPIIeoSbDm2piyA/0OBybyrtHJvxdwj6Cgnw G/4dOD15YddD3Mhi69qW7JWoRS0tPDJMI3HW8WxomBQwwMkyYthw6+4NUBwbUcOMrNpKMyy8G6u2 NBfrdAPwA+A39G8sKZshqTrHzpNYqRiLLHmLCeFMw0Pi8U4e4mMP5yGQZJwFwPX8HJo3KCbNsmyP ADfz/tv/AB9wPCvszZW9jK7sk/4pJSSLYaphiWyIcUTdzRD/AKbcK3W8XCubMYAOLITrNofGZZOO wTwCCfP7Af38BH9Mr83fcvbItV7H5xv57TdD8dLdY3LSe+8UwAuR86Gyi/O5j3NfZh7WvhVpdbr8 Uw7FKlarRZLBvL8H5o2PYVbtEqwhfJKvvi7EO1A4f3gzyGINwRmfErUCyj7JiDAIPn2DfwB9zWBc BGn6rVYEqwnasUjOCfxAVu+B2ExFTeL3ItkGRP1IGDFb/DtTuA2/DWVndBgw54Q5wHwD8fPoHSBI L74kA/gHlBbMQFuMkbmSV7YhyoglyPWoQXEOHdlkWQnh52mnfpzIT8p5wIESePgN/wDbz/Q2jslF wJFhCzMwIRyoY1eDh2qrizJcoGJFF2RX63ageh+YD2Sq3xfwOMnOWj7NsnCfPnz/ACA+APgCmVnk LqrncreVFyzxIwvlQuNvXBu/iui7QgVnQ7SJHp4nbbG2p9okb0xjxZdksNwDzTmsyYvq4eyLBM1K khwNnJNZEFUDSAiYLqUS+REMiycwDzFtgD2MBo+y4P5fFq5P8o4Wjz7f/wB/4D0ziOY6KVkWdaGV xuYBZPlmA9StFOLavUooXbS38NPQ4dbhmDuMBT3xHQ+M/WWc4ECJINgPnwG/H2BB6p+DuwOeqfEN zxJmOS3V0St8mwiBdbQ1d3li4bgHmMhia+EMIM+ruKraNwMoz7GkhP6AAH0HpkVIj5QYWelJqTUt hVBp2QZfcGx63LOFItAnG2g7jNQ8LH7qDobV2/PPDgso1X7ZsZvhCMAPoOwPx/8AQZEcbcRO642o tQkg3ZHv+No0taAp8hZsFORXUjki5eNnSq+lnDYJFdbm4QG93ZjyKxJ89G1fpbplZS2pJqq7Ox75 NZV+YMSCwdoq+JXNNw+YTYdwTLIITQbangQVqE0ZDQ2ZGBuxvfNgAb+ffwABBZCun6f5+og8BtWp K3mV81MkvsOnp4mGe7e3JaKeQreHW5jgdgTIM/BuNsiy8tHk9lCHDnaLfwACotgP0zT19sY6Dzmg DZq3VeqUPqrXkeznD4jIm207pqunr7hW7ItskNwW/wD0vtkANub4r9sweITUPwF/38AAQfAOaOno W10nOd2qSHbdRRJhIHpiu2VWLaCyaBfCAdbsit5k1wQ2qAQbQbIzDPy//qibB/8Afz+GwTcncyHd 2x6mmEjGWCSXUdgxaKWBajHmORXfMF7VMRkQgUxEtA8tpp5md4fQh0+r2F0rmbM+pNJOUkiwAj21 OchcBUmQsjMpFwmLk8CSW3eEyWFW8P5C8tgSiRaOMNfW5i38yGQhgyDBWnw9sV3x5WXgJVzsc3/H f9/AdO1pZF93F1i7vgEJMP16kxKPzoa+kbpKtiUhmHAwHsd8T9wD1z575aMs+TJ/1t58AAftgAAO hpgmCyj4n/AmIMxda0mXZCqkXQvQ90sIWm8g2e4PmXxvCq2sFtHHBmKe+nomcCG3YHjwH37B9NoO +WpUupwPfpmnwZmuYepB3kOAEe2fF0+rwGuqrX+ecwmcgtRqtpfUgb5WfF1f+tu6NV8/QQHgD6EA jKjKHkV3dUeN2WaWHcjl2wynaZa9gosXrkCubEPHGkcUZSBC6sgcxNUcVFYxuwyXjmbZcD4BU8UN lCD4LtBp7P4O9Mu9e05wca4UvTr5Up53pwotEHxPT7Uh1u4PkECQfAe2W++Xw8//AAADYPoPQHXb RZGqWo0M7Aajbsx5NkLy/D1RMFhMgGxtPYqLM+YGrfvYyV+4Th9fz/mW+zCyqMzI5zvZv/5dP0Hv +wceXXdqWhQ5e6VeG7aV6DHNrDTAC68bCWotENsUooYJ7itskPb5mo1Dr881dy1hoKds/wBkxww3 /wAAfAdMhzrBHC3IyOQugWSvavW42mUPkVLaG8ABVZHsEMcYDzIcyYPm4qTAenOJP8Dk8UerUl2O P2wPx8A/Yvx+KNK3pNKh1JzUS6afcrCbTxz6addt9SuoX6iNpEy1G1QF+pfUb6kCSVVcRLjMA4CG OSXmNkA9N4xi2LxxQ7nNrajqPvkJdM96yINb/wDEKdqyz1VST0uzHCgWj1adReou31MBDC2BqBsd RcbNlS2u3GQpF9CU4WmJzc4FY0evwzFCnm8+RLYC2dXlUNTGmMctg/VbdnxK3ZiANenQItpMVGG2 ByVMF4VBVrNH5LhqCpkitrthB4UdlDqkKC7hQWXNzYwl49UXH0pqbnSPRXhILUUFO4BYFfGP6P8A 1/XTfo9TfeJy33f3bVeeP/a/fj/QfPHlYPR78V0OwpQvKJHs0wElPB6gUd3mAVesilIGCBgPDmGP viOBH1pajh+LiiOM5v8A2AAfAYbA/ALpLavcmbWbgVM1jGG2DSajU7wBsin6ctSVpfU5SH2/mLRi +Fu1POQOW6c+MvNyFVl6/T9/9jwA/v8A0sVsfMsGYhxQ1GoFzGe27DT9YochhcXPhCarsfbdbW4c xDH1Wj2WwKQP/S9DZqzRzZsIct3wB8+/AH5+h6rX6zXLQMMaQ4RqH7MElPlTSHd4fZHa+Sdk3x8s it2Oeh9y05D4eTGdr9sOJPCTnAbdPgACCfP9NlEbpJt4GsF1LLFKkcyNdRTPEk+Eb0bDA5kGiMT0 pJpEkhLSyO7ZYEvCXXERlsI5ZIty+C2LDEhb8i8sfRuCuDVpn2/Kdqv0i2CdsiXZGpuyKfsJP2Fe qa46g7jzNQlbp5kdMggcIBvk4zDHBmxdko3vx88f8CfxPqu1WDVgZQyVabwpHqvmVtTrAn5zBL4a +CbQrlw/1UmOAdf4rPIbGyM2BRXJsyObwSdg58A/YD/ViqD1AQ1JHretK0slbrdy0ureoSQBJI9s LYErfNX3LZCe+Q6rD1uHr8PAbSHwTFmE+LjFnmxv+vkH9D/2B2VcnuCblnQ1jGJOTmUPGr0gYr22 L55kLrJXKN94J/G3BD29bav4gJ9cwyYyryjw890QnOT4DgL8AAIPVaM6uRQmo0yRalHmggjieJtW I9PvkTrg80g+pjjikKSyPs5iPMyxzRrcwh08jSaZpn0+ALTBJWgjk1ccMMke7LHFYgkndclU7uzZ WLIVWORfliQCFeuTaNpPOr62hthGGNPXyyHFKO9oVJDHp63D2ett4Vjw/Txu6MsK4t5WQaS7JNVo O/n9/wCfHz/wYSTtP7+7WBpMtTTOYOutcHwIFbCmF29ilOOci4l0TabfcMRiAF6ebj5+upZMnWLN iUO2f67POAV6wV/1V8CYTuMdmQw9jVfbYsoBG50pwW4i+n5LjEmAcVO5DxhgDmK2+Yt1fNeMWCeD ZGfdBfJkdJSdPDwffvd+P1FwHrcyCqrykejdPHZ/sypKqkw3xqovhPs1btDadhh2hp7odPZK3ZHC GjwGBt40TRrk5xWfm3bCoj5/wHVTORJp9OrOfqv7rqEQRHYjSF5RqHVp45JI1wIYRxPjlbsvaHuM 4wSSGJPSjOphkUY57pGaFe6scFprN2TiOhWyGio59kO1jTxtJw65tSLZtHmXCp15DTUNhA2ghsG8 PlJzGQeYnNvA94JsyG9swzmwM2EAIO/gOP7BhaFToxPtq6GOoV3gNv2hW9xtchbGIBZOQ5d2ptTV WnTMLrqx8W4GIJtrCfiHZsHwXgN2NKu1HqJBwAAP0P4VkFuj4GDh0hShympXMJNOOGoTT28JC2Kq /nh6k2BkT7TD2mh0/DeKlHz7U3N5q/c98q60QhwBz7HtD7H+hsG8A6zr+7GOs6ltGHPshJl9nzyu Jh4lKnFxdwhmJiFZG4LfBLQ4OGWKzV2jjKP+tVW7boBf2B+fkDDQY3ZlcnN22omaqusgGqz+Txfn 556ESoFXcO4jchCMcZFxwcnuvHImq5smx1a50T7NFo9nVCGzpNpriHqZrJorCyGCWnuTkkfLrdfx shPDuAf4bx2PfK5ME8VfEZ5tJSdgAAD6CwIJ8AATK2rmMogqmbuW7aPC842WkNQ0hEMWNu1cyjA9 DDsiHZDIvmPn798PFn54sjN7Bm9/5Af/ALB1DrYuRAV2Q8BatSAem8pSpFpcDw8tDq8Wj2NK/G9q XwnmE8g4I/b/ALjS7yWeTrOxhDeCO/efPoOHv05Q5BYvi1dQemDTlpwtB8a0mpF9P0sMfe0OBqav WACn+myGMRCRJjC+I10U9bLSGW7eGVc8kcUnEKcfcV/1L5/0gT3qXClKkc+buMfURLyzlhj5XIY1 uA+45Uw489LbE5Osm154mkyBxikk7TitfxYtwbzB+KMQpthQCp8c5UNcJR4IJIUmHIJCerlLClAU 4fDmMifagef25bWCA8OCKsi2lm2PYwmwc+/z/UPjXBV4am08NfGTJDzyQ2IPalUwJhpp5tsYC4EI kNb4e4L6eq9r60+YMqDiyM8nLRCez8fQT4A+A98Fut0+8XwDJPgunxsOBZFkL0gPpvT2GY+WhEPN FVL/AMyYhzA4/FqxH8HW3lm2tZ/ZDZzf35+fgCC/Hz9q9OWnm8tTzfW2n4VYszT+MrfJOhQNmHUg JXFOMERFUjza+5mKe5qMloszVc0+m4sX61CaxZqOHx9HoYn43X4PMYPSbBP1YV8WaeTR/TOKng9N EK16Epsk7fG3J92T2grmQCYMF2YJtxI5FMqy8RsTjJHtSx5RyU2LNeWBoAA5CUNksTT6Y7qWWNdy TG1JMTECBcGEOeAu4u0IY6HQ61jMZF/8lVeeVVsYsobQMJ4YBDYRB/7Af6YVscsgCw7bVTKN7Snn aWnkUkhLMIjlTh6VDT4bIt1XT1qOEMGe4G1Vu81A+DOMo4Q2knKiP4c+P9I2ZVbw5J+/AZiBfwut wlTfDySFx4XcVbKbfTFgLdbmOHl6/mVz2vPdnxjyr1ezE0c4k7Gg7Af2DwAAw0/5cOe4bwrraS+W Eef2zh74PrKYLlRLGck8eGMMhjkhAM1PjABasSfFxaMjYu3NufIOGL8AfkE/1HdFK90ImjveiMt7 eWGDK+A7+GwfHtonE5cCyO1yNG7JK7OhddsclMgBbXXbZscE8dKsPzD/ABMmByqTDAnm1sYPhuCQ YaAKnzLj+C38xPZHCZ8Ageaw6ys7WtbGE5v7+Afv0PgE/qkkNkCjg5loZJIE8khVNXr5wV9PaeLr lsaCm30/Mp+bahj4ZwDeHavnFvlGi3vNm+Dn7dqLz/6L9xgBxTnpYHlucpQ7GDu0Roag+0zLurC2 BcqY4J9qGENbh/DsaeQn2Mt/lDc2be6uwOb/ALAA9mDDFSsliNClpjMaZIFepJivhwNTITANgCTF jOTC5RS9fwuBzDExgDtQBffHhjJ/fFlG+km/2AB0rHF12/U2pzE/GNR9haX7rxodnzl7hXJJ/G+4 yRZoSmbVk6FcYxQ+/I93214JNDRlkLIgNDIBgblqDPQ9SDYwXNZ1P/DaIolX+Z2TmMiHDW+B78Pb UeYTGFBYxZBhKu/ER/YAH0E+AmZgN0IMh7NTTqS1WNVaSp2gq92Wx8PAYlXoYZgZLUDshiHYDJie q7FquBm2vxhzzZw+Aw590jaTeF9jsAZX0AwyO1g5xJdjh8B/DxZQsU2dfriW4Q+N/wD4ftyqHWfq 4ys+bbJjsH37z/TyZB180i0HhcU87Pk9DjVlHVT+0w7k4Qe05si/2TMVWtw2Dip7tLBh7ntYwZsj sc/7Bv8AiBAFuq0rKGQTSaYyDTO+M+DYFGCUbyxaxfbQ5N9QBjGsjDFI7WQ3ljJahk+Lxod3zl4F ckg8gr2+PVa5stkjDagPMjvYGdgjqYdocrCPC4Y9bqtwWw7gPZAe3z2pwt8YL4yMBm/yp9+QfP47 BpbGFDiqdYgaHwk52cNrd37qLceW4NAGJdwtQ2e1A62HsneDnD7axmMyyL/Y9kN/5f8AYOmohtBQ yL1ONtlrY2zqqVUnuhfBIg2GEMpYRQpiwvi2YrcOnkIXbRgQzkx5t/gePuEdggM/77A/Hz/SMvvI h0w7zVdicNODU2gVykn/ALeLF2zbiq+18ZLkAWjMxDseLPDHQNvqU8MUenusUXAG6pWHswr5+3q/ YMGCo2JQmQh0GLyBNM7XvSVGZZAlDcsYWtrt/wCJs+2SghY5FGULbfqeK3cvt5sDH8i7+K5+vAdH Y0uGLrrJbVVXr2pUjlTUPLB+LqbRKcCBgwyOEwxwM2Bq7574jI3kxm9nKu/ER/8AYAHswrQmOEDM SWjKTglnZttMjCOfElo/mijDKTWXeLIhoeLjYEyDAq/ir4jIz4rjGY5dgQ2DQT6D9Bw38+h6/bP8 J0AlLGMsjKuJ8ZskAbIHiGQXqCLfEDWBMQ9PbhMT2CHAQ+7U5bWWflDN9JSXZH2B+4Cffn/qYBsE lDJ3M0WDW7a7BXwHbNT51hXQ8VWLAiXIXt8NPfKruCkiEyDdVwKQMO9LPF1l5Oc2CHf7/iAwAH1y QOBnu71O71uynHcCcXHJFR4FFg2VGgvNirxikcvFk6MC6VlgLKEZd8ZzG4tiwBz0S2K2Mkrm0oMS Nh6bauPNGTVYds+U5SxYtbH2OHrdkquYQcad1Sp89HZFkZzy3/OGzgM+g4oPd0Bv58vRyLQUhzba ih1vOdzxJhPsj5U7Yn1fFl1ye5AYuwxfFWLY9bVdPC8h/MrPHngwZ9JCVW/vz8fQX4/v/S3pq6JC 46ZM/FJW7PDOFkfHJcGEwpVXywNczF4OyTA8z+lUOwLa+s7XaBMYj2jV3n/3/C3cepceUIWr3ClJ tGhCTRnG2FPrGvXhTZPr1o3Jdi/dgdDDwqrIh1XUsPgAzHaApzlmRncIkvJ/6CggAB/kCJ58MtKk br2RuZiOx88iBGfuxxOR49w46csGZMryI+JmpUN1tbV2eOGzBArjE+b47ZDRWc9srwNbXG2rKrdt Xw4F2kUNDKdvnLUYtsHzHC1A9Jjw9jXz/Iw1lGKcGWeEm7RePoJ/YEHzwFIVMttsCn7Gyhq2HTZj tL0zpNzNGppPTTok9LQyNqLaH8QP8zCfR6lVcMYsoe2DOEm/Ae+/v2OHTskWRQ+U8qgFsydR9Atq 5UzuYZQ94zIeFSldSot7ATLIpMutVuuzMNPOmBSCTGV4Fk9tRgfCMQIHYfoHH/UCWDSdXxbAZBd0 38pJ9jKtbie5HB15baLar0DpfcB9kMq2+GHBf2NSr+BXIfk1X9oGY4buxJOAEF+3/E+APn7DxlXV BtPgZJVl08xO4MbZXcRxtndMInkwxUMRkpJGJlkErD6oN/FJFqIo8cMVTIRnUkhI5ZkGRTLdYj2F TpmU+l2WYzmjT4+c2tWwm0TX+cyWREmi2helC8SENOfIa2n+DnWhAVWQm8vgsZ4T+gQG/wDnwAA+ NociYhtm12hMk1K23NUpZfQpg/Z5X2i2n20GTExcD5W/D2pSQG1VMcG7yrJN4SdPH7/wDYD/AFdn Uoj6G8ripnT6SoExmkpQkeYT0eWt8DU0NyqtgmB3Bw5IPZJyGQPYQ0bEWieyO7Wj78+Pr4A/7nuk jYleSIGXDaCafY9Vq5inKceKZT7f+Gfu6zU0VXC/WxlvTzLIwGNhXx6rzrDEWzPJz6S8AV8CAQT6 CAP4MaSOSobdNz7nSgKrwMu73c8ihR5vhWLQsWEeeFcSnOwaFqcVw8c+6+3xVmiFqBobk+Ozkev6 SthnxJxDmKruCwthiqZ5DcB4ZDpNPZDFgWo8T0/YwwwnTdoLPBwgTg4AB/v7f+raEK3h0OpodaT1 tuA5qeS4O32RH40Bitkp8hkJhiYYZJhBksYDqQ4P/VCuzI1Vm97qt+4Cf39BQT3U9W6mYsBsJLia Nrc9dLjGl1+hw7AXpkXFePORi4A75Scy1PZkxQyHbkPWe1lCYvmxtJ1GIIDnwDgIBB6ajxvDHcj5 bUDJ2G1TEa2JCTDsBscHNNXotczWAPyWtrgfMU85AXx5wP2z7ydzEcJsiPUXgD6Cfw6YdRlMkAXF IxkzAQrIZCU2nR4oY8Nu3yVlkzyFFKOVGGREaZmDvLMrLAV7HeT+R3GRJ8JQrzfPPSxyylmXJpva dNx4bGzqNVH+YHQ7gTy3ZtNd3xoMWhdlqLfwzNwcHbXDY7IF2YrvhNGBu3uc4ChIIDz+/hLK8V/o oQqgnzs6xzNTZNBXxX+TcxmnQ4qVqaOoaIQW2Wh9SFJy39l2D4FpreKOhXuTeTgQ5iDfj1RMGHAT 7Af05+n+p7HdKxbYlkKRKA4EuUAT1blmSMhpJ5NwcIcOyLI3hPY1UCwAK5W9zvgWs75dgQJsHviA AIOADrsIK6XLIEjMXOCckQ0lsV69+OWh2hTbZ3GcB6HDZKHcE6v6rncPfON+wt8swm8WjsgPtF// AH5IgiIZcNMULiQIunwxkaWCWRidw5Z7KKBQwonnx0Y1U8U8Uunk1IdYzEWfUZ4OIpIZQPSH9Od1 u/uB+Oq5ZOj9/sXI9DAwWeiVxP8ATmzh+ZWvqebuFwq5kxiU3MMo4TJqFyzU7MXV1ikGYID1x8zN z8gV6IsDLz5Q2GOl5+dWS9QQZYQBMIFEjTGeHLSz6a9ThlmqT1dphGRa+OHFJURRDlWKmiAcFwGL FZeaOgz61rs/nyJ04+TCsGByPYbtnR5ae+54Sb5OwBZtbNZn9/J+f31YecgH6mfwD7/9P1+j/wBT 1BWJmA+BzFd8GpOc2krIEkYbIjy3AUmqUWUyd4Lgh1uthl/4L4PA1zNZnkp7jEe7AgRHPgAGKDhf uwoOiz0DLPlC9LB0l+1CJJ8GwEIlqZ9Z4jCbXXRRwXzFKPgYQZHQrigv90I4fH2fcXfDFJq44fxx wPAWDj/TPT8xHzbgJJq5kkk+mxtkO7hwOyF4xV6YJrmxg7DakKq0O1YbBZBz8lnDBPgYtZWTlo7I jgeAgD/7AA419LLtFwEsp8yW3ULYIckp6ZpgGv2xwV4tsJsvh8OyE9PhJ7BT7wh2hPp1OrPT0UKL Kzwm0aTBW6f7RIO/8/fiVlSKVgsJchQ7TH3+axFcVzfJux+OgDNIyxNuND/y0XKvHlsl81xx+a8D rS6Q1splpK472otnly1H+stP/wAOnxKfcloO74+cfhh4adqDcNnR6WuD4C3WYxoF6hRm+YJIN+t2 oj9ur4DYD6rvBH1UUjD4u+JJsDYw2Swjr41FWBE5lFtjV+eT/mLdVzHAOQmVzAntvMCaMTaBlmA3 Z2Cfl3gID8RIKCVOmmCaj0nkqT4hyXykWokvWvQKGQs2GermvbFAmCEyHw8PuC3BfGCpUcz2ztBo ediNhN8AID8f4CAAdWWkEKzzUsDUDRQ+ocDAW71U2BP1IK7D8VydiguH8O7HDUJT8ywJirBvA9QO JNZKfo8b2EOVF+iCA/TpBkMVSsn1KJNtyCBs5IY+A0rpQ5jobyZDbLL3NlwcabtxB00ztCHUyt2S Tir0ufFPyMDidy2OK40a9mB1TtrRamUuc/W20OpU2Yz7UsiJMlPlZXdKZK/T9SEwwtmGFbsa2h4+ d4xXQybN7drgb8fAH/AY7/O2JSdiHrVre5K006sky6Rsa2dOx+jcivTH8PuAtXDr9Ph0OqzGKeyP F0j+D8mRnwpZiyEdgl2doj79/QO/n6+zHyZlWXNrpcre25soCEU2i6yRCIYxaCwr4ZCGhmFvga+4 NQ+v59VmHlmZ0J4ZkcIlGwmOwb97bAfszVDVfVMH6MJoFmXXUNXVugyTSekGcA8spTjBqUEkDZZ+ qpDmp/21Asn1rTx6hPqF75j6Ut3wYF/FAYMD2/mA2nUFS8+PzIYlcix7njhTLweWU18VZtlrJ6RE cbvWAQSnKioa9yaSsRVY15N3xW8hWCnwin3t4I07SdGYNleaL3adX9hBWi2dOMZ9DwG/Fve1sxAh 0ieAVkbLkuetBT0+l1SUlJfee4sIA/6l9eTOotgvDT7qLfK6u5vCFymnV2rHT/WWQkMMsXGEJpWq yCG4WmZh4APUb97LBsncvFoZSnt3SeDyCffsevsgevhkOsZS5yTlBIGw1fqjSbA/HKavOXG+eVuy GIb5YEydZdoWYjrYy38FcYsnMQl2HPAH9+P1FUXUkHU67KZucLstktGt80dJthfTyVsJMyKhpFI1 zSZAxDQ1vjQ8xPQ2DnK2zFOB4rOARJ4OfPv39fb/ANGNyU8+xHZGf/DQjo185WeLFUTZvjOEx9mA /Oce54qqthXg35sn9UW/qstDMinJmU75xtV5Ut1lHT8hPSE/YZabFMOENDmVXDW2Bb+evz/hjCdo adEZZ7XO1o7+AP8AgMfsCCW6LTxbQSn5VhSSWnhkZBMfJtSOWvipWheA20nj5i3DT0Iw4LbUQT58 4Nj4rjJw4ExBfr+IvAYuYXZCmazFXKA1iyab2glJiDzxgPLmPqbXqa5OLhMT+IMjgQhtSGv91Iaz teAwmcCb28AD6DsG/wCwdbUoxMAuBgoUyUmyBdm1KkV/qip9PsJbq9DdyiG4EJhiq2SHMXzHZWwF JqDsyzjijI29G3bz6DsD8/c+6HTyuIZVCPGkcm2qMLd68vCooSIeMXGPHx0UkcUrxK8kbPNt7Yg9 KOPMdyzyDMJIuKdmJok8/ietRDYANHtVvgST/MM6exumVfpO1PiQ9OZWIh10uEJtb3A+B09gD2NW n/pYicZq8nWaz7WgE/r4Afw3/f6OI9BqaRYFWT221DZ/TmebZbfkqtTNi20SndDlIZAOyfMh2QQD 1zA1ATzn9UNCNsbt2uBv2DB2i2DYOnxl3rCV47UGPIdb0yx167Ni/UkMgWW7HFqcopaloWohTDEw yvp9xdjz3w2ZGfFdmJ2pza66rQd/AAKiP7B1PGEyGertPilKrq6yExjCS6nqWYnlpiueuM9KMcws hkDh0/6PAcOVOCystGIxG3v9UHwD9wHA+AkxDKIw7wzPzAzrEtOoU5gSzxZYZiwD8gkjiyQKkhnX CesQ8auTG0bAZpIMTedAqftomjfG4WDR65p9kU0hqU2TKAv7EwUaBIezk0S65V8CKG+B2QzMHhoM 9Pno1PkybQr1msvHsE8/v/AT6+fP7ygd8KJYZtCvhK1FdPf17Gwg5D5hQ8pvltwx7K+WQY+vsldH iB6xoaN7PdZs3CbsN7+/cBAAAB/3FGQhYDRhnMaQeCKmahsksfNfE/uR8VIfP2eFZG8TCD5sI+ej uDyzC1cYTObJseL9+/gAGwMFPKFE2GBXCgdTD1pYTapL8xwX2xbTabd/ih+YUnjMhwyC3VZ4hAtR k3PBoeWY5gk72f8AoJ/f9gACUdGEjm8nRAKqsvJuz4rxQ+eeOg+oR+xGeLLyyP5qqvtH7r/U/nqN mAktIoPvdLuAk7uVYsi8QloavzCU+Vkrq6fxtDxfIfIOKz3CyzhhZGfWVh4OBN8AAO7p8B7HsRZs HlLGy08AemNoEWYNqhBww4kHAnkho42QmOFJ4p62R4qpL57EwTZmgoM3w3+wMCCf38BsHUOUQjHa M8BM16ScJUxSiGPhh5YeLFlnq5XPh2oHZHBwHuFjYsD4dp8YTFtG5o/5RBn0HgPn34AAnleQttEN PFi5jb3VD8eMVu4XRzw9hLjSpg8xitzFtbX+1d8WBPBuHGSm5vKOEN+2P37fz+HTSzRvbO6vG7LP JE1I9Y4FWq3+8UQMb+bAAnuw07IA7IjxozZSDI8iSWhuAUtemlGzXdwBTKyW56/k2rAWxoeVMtGv dO8NqIsLILtBesauU8e4Miehh0MfDg4p7bXLgjk1coM2O0f+qBiv/wBgYRTMquUYyaHsYYt1vdzU NYZBgkn8wQ00Tw1PIMlbmIcLmBhVgWi2g2QYzFBZNG3urrsBnkE+AAfv3Um6ZmYLsB8Q3evUmt3K Z4eYSDr1VuQHfgLIPhhmSn94X8a5nsKGj2QjDGj/AFxd7R9wB9+fkLnwAB05rYr/AGaqrU2Gt1K7 Kf20TQ6rMsiWnoZ4SBlGF9DDmJhiGvmK5odwrQ4HWbxF1cMZgbs7JOwH9/8AP7B0BkzpN3z3K7Ll IJFxwd3JGeFtS0oskX0alYAXC3VWLq+QPNH/AF8eSeqc6qA7hYwxxlD0NlJVe1Rqcjuw2PXrIh4b +BMD0/ups5hPcDmni0PD/aKHKMxwHik/fsd/PYbAfc1Xg49lq9Mrgagaul5STTl3D9NNkaf1Nkcn JstCUXr7gYeyFtkTw9qdj4EGt2YZ+M0Z4NJJt4Ac+4+A5+f6WItXj1yDs6AGZLkGvjIgO8fJDuBb htSu7RXMMeyTFtwW0PjYMDwNqhjHpX5ysvAQ2beMAHgN/wCfY3GtSYYA1XTN+03qWJUnqMcObj3C sq3xQxfExdjLbAhuHG4dkMAcGpMH84zcXxebM+7Xac+g+fxwPgHyahVVVEZSWZJEi1Bekb+PMv2+ njkuIybLJuVK8rGnzP1AkRnR45G0ynKeN0BEbFLF3bgDj5/V1X1GWIyc0zlyfQ9bvb41O3ehwzh1 hXALcrCq9pW6/tRP0xuFV1WQD9tLQ+CYJorOUWd8N4c4AH/bu5gA388rPWJrN1hp9J6cwNeqVP1B UqlfE/Jr0x2fQ+PJtjchW09kW7ItRgmQXxwodH5ysob5wYI7G3bfz78APn/P9KRQXrnDuatqG0rV iSrFn0pP1ULwFjIL34bSGix4bAHmocOt7I+FBxHvjUYGPO6f7J/r4/5/790txEgPGtcRaF51XKTq gZDeMiwtNQZ3fERXtcDFcOebyHhiG9lgHoFl2MHs1ZaODrB3A2lb/iB9/Pn+q2kZgAs5dEjdX/l2 Z2NEUcbMVfkB7HC482jTGQRgRhJXeSymykqNhg0b2+5VNlwoQkcnKhcdxZFe7mSzrVsYlbVzVfcz svV8huGmeWybpYVyVft8wOHmrcNwmvGJADVYcmzK5QYz/wBbA/3/ANz4DquzReGqTJmJK4m2cEaq +mamu+DTs4lPFvlOXIhmF8P8P8kMCfv1wQDk0Y8i8Bgw5shs5+h/+wdMFbXqv3DJsYynuz4uB7+l /wCDDV2GZXNOCdNB6b3UWw9buAfeOWjkNVh1n2v+zb2E9+0X+Z/rjESQaRfDVaukHUhhkz+W3Ivh z1fqaeCsaJXKaHX5i3MuAQHT1o4pL56uXAmMF2hii7I7cH+wAN/Ac+6SI5os/T+o2BHNpoZmx08O xFHGiq1Ns+CzHF87ApcLY3f+JxMYtyFo9RPHJuySSdnqynFLsklU+3u7jfWA1dfFnGrUFfBipba7 Ym7CH2PRuoC7nBD7sJr5ZA58MfMmMpB7gz2ADY1wMzyUKo3B/wAXI58AfQWA/wCfQYGwEPLSNPdP wJdkEg4FkJWE0JLIHX1q5Pviu4EPwmYZDDAYtTs9Wk6Y8o1oWgT9gmKSdQfvx8B0eUXV96Ma3DSa 0oF/ZGNJN07HrHOkWFMVzynv0xxT5geGYY7RDg9uAz3AYzU20cmB727HOA7+APn+QPyfqtDKVVH1 OJrdk21WCQqv8tX1IJ8d3h8NLW0r2QwLYdwe4cxxZLGA1/sZhnZSgtaKHHYJzh/fvP7AAP8ARGF3 ErI9YzTWK87kLRjnIcjcJHBuq4uxQmjVRGylkkhWKOZhFGg2pYZWZzFEuN4KoBz8khhiVL+78Ibv YFkapU3THV1kJE0ZdxBVVpF3TFdXh4HnBgtSt4a2ycfw4k37GhkyaGhsxP8AZDj8/AAHAV8AggBW n7QuS1cxVzbVs5tcANbjXdPqtkYG1bigdhira+4VXMT7UZLBfOedpTm2PLQhjFk46pKScAH/AGAb Afx63Mg9PqCl7OMu9hSaf5UpQ63rE9IXlsWmlvih6fmB4Yean/Dg0s4AQd8DWb+KBmWXkJdiS8b+ vv3/AE62xmySLr8Or3Sn3HW7QAuSsgwG/iC9sKGkcyqtgmQ3CyA+I9beP2MPzkXaH0c27VccPnwA Dfz/AJ+2eLFmUJLg5QhlHFFOQbNZWbFfA5vwMZlVXiCw6YjG5GNSTAkdpahuSA3tpxeTix1JVAKj 6lqQPJEW5tJh6BDf6dpCHWLgkrcrU+7IlyXAPuBkL1xT5iAhKoK8QTxiz4oVoE8AnpdqTA+7AAQM V/A/isswPQdy0nkwEivbIG0/C1aJDxnDR8sOhymx8Q0/h8yG4MnHjJwCwXxXJjgqHpyWdQuyBHaq 34/v4BAPoOwM2TmK+LAH+eh6eLaQ0M5bA+t5lbyrsTbQs09KD2AYp+1FuGH/AJ5t+eCcBiNV9NrL N924OAP7+g/fwHX0xV9brF4AYqRkqUPNJDUiwCUNplmJQFhlC7s5gt8kidn3CnYFwT/mExhRX8Gb 8H9BPnz/ALoOORg8cpZDNDjMJoyoxj5rJUf+r4AY4qEscHLjSJKAOWOUO17Ih4x7riiiur8Nl4sE c2jbchWzPZ7mA1UnoDJpufLaU+B1LaNZMiETLC9PtqfD3gwGDfMOIZDfU8ms3ILGIyOECdq9gfsO fAEHqy0e+flXBYUqwKxGodX2QyS3DJ09o9sGK5F1khy1tgDmKrW3yHV62cfKvPWNW6M8+ywio5vm 3PtgAP5/36ZDZX+ZYy3fGuvKz2RcXA7Ip1/c1/cemRbGrKxmgxyRkuCt63Q2BwOT1/BHuCoBnF3p ZOG/B4P+HPj+/gAClCMiG0WJMgFGp/vJSrF/dyHAzAlDld7qbAoe8YGIcwOPMToC++HGQZ7oe2f1 sE4CffsQD9v/AFdBjKsLbTumASMbTm/mVLaqrt5N23IA6GPdj+nzXcSGaMtNKdyBcv8ADMw3DeJy zaQ2Bjjze5f5JkZBKFOhhSBOOcMTi2FZURZdjV+PKNU3Md5oxSMIxlOyIQiJnM/qw9A1kBDWvOke uQdKBVKObgJKznQIQtGsq7aHtXXrGvWlErF5ZWpDrkFptJN4MCq2LOxsaPkATXpvsTIzFz0k2wpl K+RN9EvPyFnJEYZWfGg+qGJG502lPkWfk8cn8+Ok7jDgcAcAWTQ/1sf+Oq0HHyZfD6ku6GtxaTQ+ 6IlfJXlyFwpGpd0iTCAeq63hh1uwO4wFfpZqcFkYrtAyzDiTzYGg/wBAoOwdW09fdRXMQ2iKY0uP ltaY41ZV+Ntqv2GGmlGFyira+yIa2GDp9gTAfnsK3ZllpfKg/vgI+BfvPgD5/oPh5jhaCGSDNuTU teoY1bE1uhzF+snByq8TEF4kFrAxDD2RvCqeHeYWCau0IyMDCJPOPP7AAAdcZhOeBbQn5rkq1vai 4NUl6n+1afEcEOK7s74t9k3AOHZOPhzk8g+TeM9+FcZsdXOrtv8AwHwHTJysm4ZAkvoy7kB3dx4J MMdvamisylDnkDhgtXkaKKQwXw66hJpJBIg0zQLIBqdNIDpdTpNT/eF7JBqUmjuyrRGlZVvHj5Vg 5i3pplV4/h59zLdsXRW7s72En02UYbulTB9b6kNPYcOGq/2UrAbdnrMYUFsxPwloo+//AOT8f6PJ 9qL+TImNFtDbRZLfyZPyOYPBaYKTUh8AzHBDQ63vgPMxDwVJggI8Pym2Mxw3ibR0HsGAQUEAePn3 xYGZS93Xo60hmuNS1u7zNTNmo9e1vX66HfLa09nq5mJ/JA/w4ZCZ34cLa+YzUarlBhNH+78BPgD5 8+AQQADjkWQ6QKzuAe+VjaNhSiSTYRiZW4/gZQWWfFfh6GyIThjZBAw1VLjWnG9r7NrJN4N1cbCW 6Aw2B+Pn37pYCtGoCPvZqlsuG1nQqrbdR8e9PTsqvd0To2RLOiIyM7RRvNLH2YUY1llbYkGfa65e eVPFG6PWeoC1XhJUharGW+3oN4q+vXxos2Grvks9Kqv5jgyIb5W7B7gbQREen3mzKbq95GVW7BAm /oL9v/sffuqrUWnyEggGXLaW+6laGJLZtwcfLcCl3CU18h1eHMLftDHp87kCHanBkYWUJvPCTbv9 BfgB8/8AriyFOh67Pj2+K0Hqchob4tlmDTq1EKcMHgIlyAhx5iZT8MPMT1uxlKrm2q4ZPug0PPOE mrsAYB+PnwGCDsHUOLZLwQ2TOn6aQ5LJY6rf94h20ru8Kxk1TilJi/MW4eAdbtBbB4r885Mo0W0V fZm+BAex8/AAH7YT4Dq0XPcEOy+4U22haUOcbunklnwFMvgc85eBVPatG2Miwx5KyyNFJEjnDNWW KCDPGhRYi77QCTYrIaAeU0ZMqyw9tWdb+SN28lvDu4yosuLKp8hai2yMjJw+ZB++Kq3cCN2bZiYN 3NpJzHgB/wDEfnzZbH5dfB09klVjGAhskaXDGLCYBLIeQ6yPRQ+8cwhzMGBwgz0/BVmjbMxfBjN5 tJB/19/t8+H6n19fukO7O7Gqya9PEtpcEO5pCOYPW0vOTRDYeSJ8xkQx8wH9tamQmzFENlrMGku1 XcBPgNgPn2DYDVGhWfKcKlPAXx2L2DlG1QAHyZ/AicphjaX09wxrirFu1GRgMfAYIOIcoUrBXt8m DNu2OLBUW/sABgAbAaurQxiCN48ssBKMHhrC805vO7HcKxvm+AK4yM7ncwxrGDdQ5VeD7i+Pnt/H XJaDQUFujhRkqq2S1E2vUCnLYT2qMJW3LUYkbpuD58wwyQ18wjntN56Djtiuh4kzn0nABi/AOfeA QtNd4L6kyVi5W0kySUUxJiVe7Eg9hQ0I9wOLMvD6eyOAev2ScBIYA1sZumFmDAn+lZ/gP7/ieAFT WvtGbDPVUkOrvnDyRJ3/AMaG4WFMfFdIcvhj5iEHT6rMD3AHA4kq2TZnsr+c3ukzmwfv+wYvyrre 1HwADyQwsaEs5ImLcveLUR3dkcorY+NEMfDM3Ah4LbgHOTyAJVMcG4uTJfSfPoOIE+/b+f6kZKhU BxdETdXz4Jaef/75GZylcZ45H3EWVciwV9lv4g64VVZ/LWfaD4oUOb4Ox9bq9q1PVenO6clAGik9 tXmAlbauvb80MKa+Q94rd85gHTpk5TQK0BcZZtrGLIMJaLtv+wHwPuwIKCLTGRPnq56AZJDHbKJK TCr0y1I93GJQASLF2o4GO6lJh+QBwdLOD4D4yTFq254/dge//wBQHz4EBx2g2dguSXTRmrpJya0V Qleq8Ozh6RMGShIFomL5hwZafQ5g/wA8wITvue6C/Y54QHv4ABv4A/07LMh0PXw/4DRqo08TLafU CJaLIByJYdNsZTF2hgQmBw9kbxaENHbWBSgp6wzbosoqO7BcN/7ugOPvwHpK6mNGhR5Uz1r6iXTq 8WRlk3RLPgpdJIY03ogiSR8ckMwLBXfTA7srB0TTJDHKUatqMZbKng5cCQg9vj99D7ws1cV0e1nf 6lkZD5qNX7zkZLjXBl0jK1iRMKoxJt+EJNrqGuhxxH1HtjGrQ0j6R2Pqs40d9GIM96MM02weoXcB gOkYdM2WZcFE8Luxbr1Xpmvaf1CGavilq51BTCDKhzLssgPR5jltwVK1B8EYor/o7hNiAPwA/wDX z+wKfUownbBt4FrfO6hBkw9njofqEY8clAS262KxgUIMyQoiGOtSG9rwL/mR/wDmZiS1h6fUFNr2 KHgwYrx0/hb1w031IuSElNrpqf6rfIY2ZdF/ZOsivYYGpYlntAdfmXu4p7ItjoSrWdoKbutrAzF8 Gc5CGucgAB/E+AQfcAyBZI29SeaZJZp5ADHuSBJJd1InkzXLbMhUNiMrJxXpbtHNJNKUhiWLaikC kh5HjjjiaVErvzEYLLkNu6yfKweq/D7LUyWw2cyNTGq1cvVv8xwr1baIrDY/JPmLe8dkx9qQf4sP 4jHzBZFtDw8nObOzyg8f93722CsZSq74Rw6Gk1zVa2ebc6NL/wAFkR0hD+VEsauQ49PWzDIYDj6r g8gAtTITGNH1lH5sb58AQQD9bvn8Y28Ecdcld17aGaBN1iTW7As2pySfU68IAyq9KFHBfvhPT3Bb mD63BTyB6cybmrtCz5urgmwP2HgH4AAAWKSx+oS8ymdXObnb9FshbLDzyTfCnZEqm14CruDhfDh3 4MOBDlSGQA2pDZvF8mR3Z3Sfv2P7Af6GLEIqK6epkriRtuSKSGV43Ro6a/aCDkPcRXbZkuW9uPFM ryJHJxHUbRuexkjyqO6axbXS/jlVh5At3OJNlqS3xszxJ3IOyTyExKtuXYxT8J1u+Id8TMFuehp6 HeC2ss1X03uf3bz/AP1fvcABrdF2RcEg+Lys42BzbIuOvQ6HcweXDqWuWE8eT2BPMVXZDIYIcV7g cqTyaz2v+j2ib+gv37+A4D01MzTnDXKbY5V0nuK21YRthq+2qNreLMFxSz4rw2CZW9kOEyHYENHP fAhLazjV+2LLwECJLxv/AN+PoOwdJ9taNUDG8WplRc6rSQG1BlOZ+TTKO2YuSbqaF6jFsfpvT2RP D3wPMA60uF8VU/bLkfWZZB3YkhDmwAD6CwHwAA+cSojGPchlmGmZJISYpETZC7rOXljilwDoRtSP 7jlha5grZNDupKqI4jB07dkcbY7aiPHjHFrJbvvwtcyQqrNQFdI4eeFziIdIs0LZsdcvLPiB4qvZ h/FOf1x8DTUOyGFwOfltpxJLT4rec97rqxAYAFugAD9sGMllg1+UUocM72FRVelLItp3rYxbVLu9 byjynbVX8gY8GRkT1vGacn1/ypwJsyx3fRnfD6Og7Af8+gdPfU+O9CtbZcVBrJ3pWNTDGpcr0+LD uGvhE0+AUIOOtQPiiGG8/LVJ+LBYz4z4q9XrCxhhg7pHAMMDy+f4+ATUhTW3G2APtknEmgrCQHdo ZLOYF4OUixHLjfzFsuyGGRfmHFLibVxndBlmE3j/AFUAIP8AQP2BguNp3jcNH9O8qSJHJlu45xvE x22VY3rcDVIjeKGNk9Nk2A6iJ91BjuKVxvGWGVecmr+Jh4PuJ+KIohw7FqV4aoDmeJXNpLh207mK rqu2C3A64tg8BhuDJMT3yGydyIFaEHw4hLL1V6GzbFve9gAADYOfdb7ImHa5zM7NtDO+ZAmcTvgl Z1btkOLtDR8wfD4eY5hxsHB4HOfCbyLtAZ7b2bOn0E/5/HE/0wo7I6Zws9Xxm4H/AOek2ku2A+Dr JiLb4mrzRKTyIdkcIcOYnuE5SuADOh8ZF4o2+cKq79g3/wA/0pZGOUGtyG+McyNui2bU2BbziCR3 GTe428EWRDQ7IDQx/nqPIQec/aFnE4ESLRR6ifgG/wDnwHQkqJZpMacQx54vLtttA1hC8jxQ3uG9 pVyoZ5YriUHqGOIdqPMcR7sN3AH8ZViPxZvx02ocx5Frd2IbbXoQlXyTaKQ8OyePh3BxeJz1DT+B snzJY8wqwGE9BME0ah7k/rbulhsB8Af9uP8AS95BCcjjIpUiBk5OUkuy9V57JqBhLi2hITYvME8w YhOCJw8G2j3ydM/a2Zm+7bJsGKCfPv3gJJHOajG23LJdzNnSZkXV0S3BwD1vdyfYwtsxaLs2dPrd 8hp6fNeKWYENqcNzq9Xedj7pBEc+g7+A4DwLrTMdJrat9qotPNuF3EtSDDX+cSX7YtVNu6skPnlf 4h9MbJSZn4e/YNtqGLMeavfO5jwb7pI5/oUfKJ9xt2Y4mMQTVo5o7xzEeBBqRZY6LEdl33UsZanj bJ4Mr9cx1JDQj7lOfEZupX+3s7WviHaF+2KH1AV6xmRuJ5pDjVPcnaOJfE0BLu5NZF987qWpW918 bsbvBPVQ6MTaFcYLB8JdufW79+2ABj0n4Zy3CjJnGaqMVuYPTJMsPZAFH4eUtphi/D424THCYHHz J1lr6i1B+c90ODPBvhJw+/b/AFFv/IAF6pAezNOdsDLubZi3p7q98ktqO7ZweIttDQvSleq2Bw7V zKrMD/gz9SGANQWUZoaBn+9jiCAfj59+ftg6SbJmUWpL9VocVVjW1qgmXGJsi2s6RcYepa51CaX3 wPaExPhoZd8YA7x3QPYLayMV9zGHNjdkd+AfoAftgt0NJJBMjajTSzTQvgoeGTP1IzjMjDEVtyBo wwJzxLUtY9TUrPG0MMsCZruhg0PrsXl31Y9/ru0cqNI9x1kvab6FbEF0m22pT6lQ9ekhtlnkCspA 2vU+VgUaBJQpVae+sjhSaHD558BAbZ1kExituayc7o1dgf4Cvn/Y/v6rkZcNDQxuU0TH/HKyUBeq ca1EHcO0OSnUvJE9xiUmYmMpCYqga/RPJk6v4MjA7RSTbx/X4Dz9RAHYU2OquzNZprtvzuHdqnsD WAtmEgxXNoUg0HqrHh7Ip4xcHIIdjceAznwmMF1esjDjtzYHi/eAqMBsHUbI+PbS+BpKBMCXAuNS lMtAbDr9HmafZRYXV6e4LbIGmskIgyHANgNoMPWbPclX8mBpNXBPvwAAf58f61bnpwRu288WeEzC pBnt5Z8nP2rj7caPm+EqOdThwHdFMX/M27o52MazPGJ8+b56nhdqPjHUde1KnVXpL066oA5u+bYP Xwr3GnnrGmaQFdkcDDhW7JMhkIeLbqArOd953QYzc2CJNV4n0EBsB8/7KW0LYsS+XAOUzVsbZ2bD W4iuSs7TvU8yLKXkIX/JzGQwn9r6eakMhAOYrNvtDSzI1VpPa44AAH37/wA+cEeu5FLWxZ0WUeJc jyJNe2DeVPtAlku6KplKHtQeydh2QN8AxB2+BB4N+ZOTfdqTOfv/AGiAP+HRHT90U/3s1QwFca/q upskt1lT4ft/YTJKV2zSq0GR0O0w4eG4J63ObV98eDHiyjMipBukwfn363d/AffkSYaYTSNvOgeF I1j/AJFzyLBpebjWhsx4DbJfubLg4y+pIjiiUOEllmcjNBHFGZC0cXbt1gQwzYMGU2MKeC1AVHej Rp7AUvb8Mk4bMNEWBDd6vE4/FYUOrzDiYmUOYDh7AZK5rSwICraizxe0FoY8d7eDoPPrd8Af391w G3U3gdvioH3PWrTKaIwunAvad2WDXy1p8PJKxbS0nsweWXp+aoN/bUht729Vo+PmHdQ3aKQbt7Hg OO/efpRV9D1PY0NkrmKh6kKrq88SSK/3IfYVcRQNm7CtpxiF4dPr9bBcwP2NM/F5Xa3g3/QPn8D5 8A/gLOB6juOBRdcakQucSZfmKdhBhx7uaYpHUZcVNgXBeqyZMMMkxwtRHuhgntJkYMwF2YzAjYW7 MV9/AANgQffpbRKZQpeFJotVJKjSLqpYxHrsFGEk7CJpBFDKkscDvt7iNIwGCto3nkjLR7xSaHTa eZIvpVAfRxLGHP0mMYgSQpqDNtR4QxzNg+B6p8ZaA+oYqRfVX/h/N18BcidNXYbjXxXOqRLDRxkv OkQq7W1A2p3QQyxFcDZ8JOgkfQ+TQ02MJyuLDg6nlAx2RnTcyCeqt3Fg8yuKyqnNTlUPERwcZMVd U3E4MBZxzYkL0rk9ZbQK6WDFIXrjMQ6WEBBRkOKaywcQXCyxGGT6c66BfVMbWLJSbU5AWDjRrE1f HH7P5HXElYLLIsg0m4sjq+WkDNmrYtbb4s3dmhfcaHFbbYZAbkLMWNPQ6lcLGzqBqe+KTAo7u4K8 VsZ4r44WnZBhlcIbhMau6Fl1X9ZwfCbMDSdUTtVeCCeAH7dxQetxCn148HmARdpkqZ1BQ1uwsEms DHvqMPMMpnWx5gwxw3DmGAQ84IhtwWVlWtDAm8BLR/7AfYKiAP3VnFZskSqnMZVfDKuuDudpveCH +CYLOFcuTBSNc3Ynww/JNnq8PBAELaarUWXkoUvIZgb2T78ffgB8/wAgwQ+MyqzzIBV1dDjZLc7P +I9P4OWDlHy2N04fMWw62t7gH+BpvvjEztjQURucc2/QBz7/AHB1h0k27Gjp27XokFonywAIa4pX xu/B8fBbnHsarT7TMFVzDI7PEVMsQF4ZD1YVzq15HjmxyOq92AvuikL0xtoYaEybkqWNfK/atwVu JfENod7GTofezF87qQx5gH3AQ2oPyYoLGE+bf5/XwAA+APnyS3LIZJRAOLfNPZvT2+Xxx60JlkWB LZJSuWptyWyHA7thh09xcO9K/AnWQsMuozuZZtqXZ/Xx8+f8Af6xkMTKqONVagSbIt7CS+OYmJ9h MhR8EOVc4sFbraGYmMjAH+AQgQcO2ZTdCRw3vYM/z4+fAbBsFqF/LqSfD2GVqcJWdFJSWG+CQG8E jADYy85Sg/GzCfMMMhCZ+L8Hhk8oU5Mcq427YgNg38/7bBrYyx6qA9wSOGSAs+7LhH6e2AiQyRkr 32JUN2MMe68ymNIZHjjh733HuLFBI9ZM75HHKhiMT4PSZQnmO0Q69XBdM1KnpoEIJR7IyrYvnmSH LlAZg+Gn2QhvlkMCGcUh6kq3Yzdr7kZlo4E84goJ9+t3YAGwGpQxlu9uPi5PGkk+VMW2wwquxhIf ClSsIs8yMBhDrek2Snx4eah8SR4ZPgb5xk54TfwGwbB5/qT4utHk/JbWMwgWE7n41e1+4WF292vk IFNW2CGY09uH18PBPME8Hhp6ZuBrP73i87+/ff8ApSrcxCXEMwuT9yASoaQJT2Q8HXlw8h90Dz4v zORzIfH4bVAsA8D2xZ/GZOq//IPv3H/P4yyRyMIhgnaBHBEFjQg81GsgjS7HsRMvuugV1rI9BZBk 7I6GVjcj5GM27sDI+NcCSRqJOONtkeIeZYDHW54g+reDVV8xkU6fJXAvy4dIgacPAZifDZLgh1un r4dHx03oc4wsszRaCz5sJ7YbB4B+6kmysng88E/+HhQ9wU5ZzQHbRIdJhtMQwUoewhYDTfYFwTLI MMktgho8Bf007PwZoV/7JaP5dQUHf8eAgAmO0EHJwdnx8fHdVtAkyWEHSXztlz2pVNXihwC3vAdk D/MrkCwNtcrQxZ4GTrMHV3CarAIOPHz4ABsAGHru2Fev7apZDdn9VSLOqWIn0PM1EFltyOr0UWYH 1uHsik2QPaAfgZCfOD9jWi0NsBhMMcNgPgAC/v8Ah1qni2I4XEaZ1G0emdc9uSSgpMtj1IMS80eA xiDyZHbxbNE6s7BjeUIlE3JMn+XD4xv3ZNeVUKrq0QiOYn2QeXNhdjD5pdtGvU48Nj2En21dzxfE pPIbOZZLUhuEyceTz1qJ6yTaKvqDfDYRKOAD5/8AoE/j0mVdsT4zJYRRcyWTCtDwSvXBqhyJcKUL iSmgOoTLIDp5iYvrUH6G8bmMKNFZk98N1d9+P7+A58fAGDBVYPTSl1UuXxMNnmRJf4lXkr+q+wkI CrLzRV63aHeAPW6e+OCccA2h85bZifF3nY+bXZz7YPdC4Cf6kcuyO0tuZItcUHb5WcNbI4cOrsNP uUosmi7gXzBhwW2VDHzFXcHw4n0b4uoGZ582Dx/oH+/qjhY59zyKmFLp2uqvYLmuNn1MeDnmfbjz RbcpHVHy7ULrkdw1ii8ityjZ5rHgE9QWa6A4tZ51IpC2pGLBz4zuHApFgFob4mu55XtRwtSt2Sk3 wxX/AIBgn1zgzLKHqMWRhzzaOggN/Ab/AL/0EpbRSdc0GYsEo+US4ZphblkNOqTaCRZG/CHJDcHG HD+HfAer+K2WwUt8wneZRD8HvZvtHsFu+AP7+1DDALpvMpmLzy2rOsamba7PodV8hT8a5K1zaHcD upDZPx+HsbFOgcb3MWLJ7HshwHyAB/X3gFLHt2v0jT+SqV3Drct8VYzDIs488MIcoBYSj44WA4If 4rZPhvFaWApVWh1msi3zbNkdsMT6Dv5/nwDrRGz2dwuiDUxuXR8aDhqBXHuPbxyOifnEDl9nYiX8 xqVxGX+Tn45LE9oHQHMj6kKqqv5WbDQM8yyah0jvMS8MBqX+HSUnp9PrfdQO4L7IjoZ/uoyE3nnh NmeXbZHjn4BB4Dh1aKY6Mi5NZD3JFJkY3AbYSPqEMNFesgBN+XYwciyIdqVWh7gHnASECDW6M81f cnGQbsb33339BAe5/pevi2wLrhMDMd5qVnC6frcsr5z7Hdy9oCmEDF28wtobInzR4fnlf8VmE8EM XZntaPCfoO/7AhYn+rWkhFEKJNO01T7q04oraYp11f8AJzX6py1yPpVnfRI4NjpZZe1vq9Lxx1eg TVqzqdfGZa31JB+lgwOoDF6gB70455GilaMOyQJKgdhpXpyTVLuV2Y2SDi12eBXLIYnHfCvrI+2Z b5d1i06RqE+NwRufccfHd5688pFbvFgyBsU8NNl7BDkpZBks5XxDlCjDFFzPhp8x8Q5g9ctRSYJ4 OEzfff3v38B+gDYNgfC+jQz1b5zIr5PG1d2CKZA8eX7YZLupGX8WyO2ye4WQYMD5kBScYAP6yUGE yfNgiT5894Dfz/SlHvke1QeUUrmZZBhIW1tIaCRjj33KhnyVMsCHadVmGTh/wXxf/nFhGV0NZJ9r sXc5v/4j2DYEF8V2vzLHS7gbXKZGZA1etteyNXTvS5YOAtBUi20YXzFDviehp4/5z4QfOBsyy0U3 +9728Pz8/AH7wHTZFxs37yPSngt5scWW5d0fxSbb+w3Vdt2M8MzDEqMtzztT1jiQe47Zu748VR8/ A44L48NMAlGiwpDIhpDs2K7tnL/zK5PFgNc8vDzMZi3DX7gB1KOfDnB1lDfKzKcJSQhxB2A/9+fu oxgrewVLMJ1emrYwxk3MNSJFtAVdImi0O40OLuHA3xkcLUX+VcefOYDLM4GMWarSQgSqwDAAQfoI Dpy6pZAtjqutwNczBx7BbpwSPmZ3b1wjHWxDsZw+YyGHu1Ia+YeABCfBZOc1eLZhhxJq7YwGwf8A Woj6m0/5ZieUtq1ClVyVVt06qImQBJGGwMhnogu0A7gHoZw3ityExqPWhdM7k15K+2IxxJNuwM+A AAEFAfvfrPNOzQK4R5sskQIZVwrHZhO3LHeVv3tftNJ8F0KpuMmSR+1WLty8bVmgFfNAk2aIujdd DZys0NNzM5cAocbNngfMW04ODCYu4pMuRDZCG8Pn1vEw1AV8D8zc+UEvN/ePPf5P3IDA4cD4NhKK ZmKL4uDRrCrjUOyCxgWsMKHKDp6HDZKTMQsA4Oy/gKvBhgsoT2Pe6uBnwB/+n37phR49qttD0CGq BkoqHZa3GbNP4GjY4lPaLasIDYwdwmWpyQPyDY7LX/dP5NV74zDEfZN8+g7/AOfwPqQfmpykhy7o WLgHAMqmkikrZzpph2UKlu1de3KGnYVxMqCJ+9tkCBBqwnWYsmNetl9SQcYEHABjvwE/1od42UCQ vUm9EIlfDPExWxcqwGNihifJ56FWOeCsnZsTWkQjuw9KRk1+3hr4/H5f6upyJ9gTNPrHXo2Grvhq vUckYviJMA0kJ4bDI+y3MtNbsBwVYCe2gw7NxdoWazOcJNo4D28A+n9gqvdGZXdyOFtZtaTGShw1 tKUOOTr2v20wLFyyibMH2Qt1u+GJjB8Gy/gNUzkyELZkbuibCG/xF1YoWh6IItRzDzvalf5+rQlf +nyhlAbS8X+IvS/hugZPZO9reySyDh/Et8CDDZWa5GhZZ8OE2hwIAfqIAfwXzx9P2BU8fNyyR5WM 2QSnzKK7gMmS0CQ9XuVZFKlRHAwn91FsOQ4q+VepVXxm3/syy8ah/wDqAPn/AO/1E6Fy0JfHONoW dMMcLDFBk2aPkMJLX2kY/gZI14V1Qvg6NNFJchzCcq2HpgY8juzJ5rEW5g7RbivR9YoZ6wrRzk6p G2IQQxpASn2MerIDF28xDtRbZOPuFqPlfb44M21q7NZlqcJdvcBwHtCA38BV1xT7EMsmSm5tkMjt lDYy9V9b2Q4MNkNDl2vKPnchDmGOeDpmCIvoZwOT/wB873vhzf8AYEEBsC/0wijAUocWZXZ4Bbhr bsEr2v3yt5Esw+AWFo+GwMaHcExkQyCGDfU+fOcCdmIauTGbIbSAaCBfqEwPgOegLFVXYGZQVbh9 UsowSPZo1Ss2v4bsHlh/5vUDbSePmQ+H8bIOAM9XzajiFlZVyjMzeENvHPgHAQCCfw6QZjQMkTd7 okmYx3S3tYcGsO7jm8hRFDp2ywYqs5Wu1mjekSQe8O39OWOxsyU3LSdvHVM3BgshttAw+NEMaeaB ra2ELOVbQlsktNYHJo4+t1u9uEOq9nNqXwDYcYzbWMWQaT+m/n9g/YOo14rpLcjA356rXFbmT0nu xnGCMvnh6zXKKYT/AKeh6kMWCt0aA4Ad4WWZX7mEwZvZAXPvbf373PuDVo6A1KxE8zVWdq9PBrCU kgzpv1OvC8tpp7mSG4p8O1FuYYWyENIn1/PrjBGwQ33H8o+c2B+59gAQX5BWIMgV08OB+UUGjVrh MlhjzKfMNheLVyRaDQt2hDQ3xPW4ZAxzyBUsFw2ztezE9ktFJeOfAMEHwGwakAECJAm3CbISGCXf kkJUTO0MqxZwTRFo1VZDnkzErgA6mSZZi8w3nimEJb2FyaKNXfjjIkcmNm8KyF5B2V3XdN1VYlwX TFfGPJvM83THm1GV4EuF8VKJFoYcfwNkmTDDAYxbcLa3d5GK9yLTMcwSAm/0GfAc+fkJ+6TMyzHz NpdkMgclAre2tOpsTIsIC4JCHUp6wnxomV/MT2TGyJt4Pm/YobXyZFxKVmso4QJV2KDv78APv3Vj wWnDVHRFZ46lq9BKKtVWqZTvlWXM6pqnreubQuKiGlawfWQvaqGXsBw7Z1AeVKsWGgozrLM8HEkF j6f0w5DgAYKvSOcUO4WFX1g8bT1w8/qYC04dkWEhyiktNcjC/wBh+5DHW7BaiO908pI7Kzk7kuRG GA97SQfH78AH/YB0lFDRnHCeGKoGWMxRxnSRcSBUihXbxkLpy0mWIYYWVIsZmKK2cM3NZIOZ3xuh Yvdx5H2FB7r4sUpoepAWDGu75bVXNQtpUrNtAbwdIW2ixpYur8V8P3U2dDr9k98J7wyWbWb4UJkz gTE3/wDuDf8AqSgUeQtq5E+vq5uCyBuaeoqXfBL7DwMA7q7kH5gyJweZMIB1We4wAbJ71erk+DhP 7/bu/gAD8AAQMys4eVbGzQBqAHbYdWqY/THbQaIyK8WwpQsPxsxCreGHsBbB3Sn3wcmdjWi5FlZR wlo7H3dYOAoNunz/AE7GSPXbbYFkHoqStja+cBrvfAYNUCm4FEPTgeFwx8PeJhgOPT657gIljTNz V3zFmRwiSE2A/gAP7Afx6kZaNICVyyUF1ghxjMdpsxhMzht2/dbbmXtTHlrkI7K60hplDHJ2ckbs jvS5Z0lLiMAG5N8VLHp8Iqn1v+Wo1nVpnVc72BW4ej1NbKPkQCBcGBPcJlqckr9bx08b68LbwzFC gx5OJKSkg9/qI/h2iQj/AFuV1Nnq9XJSq+shbW2iYSu6Qq6kK3dzBRWli2gPX8yZ4cwQl+PA6jIa zujQjMxzzaO/H37ABz/7AbR8u2KqkEqbH/Gs4WSNiTGc7OFeuBQ8plDzi4VuY+ZdgdP5V2v2PAZw PcyQNJdwnPj4DD78fQeoGZfK/mnFUWxku2KGhv6lHA1Wjyw74r6ZSiHah9wMMlbvi24OGqitGE81 GBmoUoLWSe972DAIAABbuIDqmkpWbZSS3Mqh+bjcJhga/kkwbFPuxvIV0UUKs6nfmR19jZ3yACOK HiRI5PPOGPF5Cq2rRvtdtaKwcke6aQpYa7UwqPE6Gq6nylJ+l9JuZ1sZ8bCY4R90MTLHc5wwqMWG u3sM2L6nowqSZJCJgahlJMnOvRxZqKrLrREB2O2PUsqBmrs2AmzmVezobSYSMhtZ5QBnZhGFXgDg kw5+mbIcszB0jS3g7FPxG5oKECTFmSPVnXOT+2Y4lWPZvABL+p0ougBdbxq/NWf9fNaJP7MiaR2Q 0rMWUbOqNAkEDnT/AKHSwmKdkafbYMVfSztJrKwQMksQyWSmLuDOQEsmylse4dt2RwW2Bb37CfB/ 2uTGA6T/AM8QCDjsAEB1VEhX4dyU6xss8Nq64M3OpSJaFhViwNgeubQmW0BuCv8AT3yRjwDr0yuY DhAnQlkYrq7MzVX9JOe2/n+mQwHV8OLyQy5T+ngwL06u7YrslhK9hWRcibqEAnmQgXhzQ4f6fBQ6 uAnMWYmr7Z4PELsHPn7fwG/9XY076U3wrp/tW/f4qGTS7eaqgc4tRbsBemJqu2aVSiGPmLbgH9vh 88o88D8Yh7mTOVdV/BwCCfX+fAPAdCWX6YPOghhlaYQbs8W3G8n9MFs2xvu+DX76XGAzIjl5FKI8 Y072Y8j3BzjzeK4njw3Hx1VGsw6e0R2R3qqpdnXIdgcwWzFTsJf6RbVSB+eB3yGt1WQmcTr98g8G eUN8ZlkGkmknwHPuA/r1PJ7A0am18bQ4Gq7IsJoW3+zQ7JqQHu5ix65bIt8GLQuH7gHmbPBgYd1L HGPO10bZm9u30Hf+Qfr0gaXmR5UfOFq4G41t3hya9eGri9ZIcrdmhNXB5i4GXh62wvgOfv1VoZMY hqywM+k7Hv58Bv4DpkSGBgyhcOUm3AyadcrmpYxnWEviQ9cxmxNKTK+Ww7gtw4fw2ptXzzUHGcXV 2ZGObJvu/gT4D+wVqF+pZZL/ALzC6nSqZthGjU8wyy4SdntyGHfx7ceU6eVEKB3cadgd8xxbsgxx CYxZpndtfetfu+rOWRbkjTmpuBnVAHGkor4SlyD1qWRgYqWxqytCN9PDrbJDh8DBHp/B2R5ZlcX2 zOO2yO4A+/AP0AdNQJVC2eH9tAy1RS2esJbs28A56wL5m0Ohy9PoFcX4a2hp8vbpiOBYa0nWojM1 YNKys8JtGrngAwY8BXz7+BAV1aFqyNdaHYSbqWyVtkQ0O7EhouB2MCeGtES0LGrev63Qk7h9br75 Yz4wQAYf9RdQfSMLR3/n3uAAb/0mVPlAvWWt2M7jQlkHhslTp+pSWpBIMVKelpqaHn1Wnp5in63o 8P20+qh/KIfnDex7/wCfPvx8BsBwLGiPJG6CWFMp42jExj8BAIs03s6ezlHgR4fPtfIiExKiSrpJ XCRBjsyN7ci6U+ONjEZEnI8iuSogyZYsOBaEh2CQ8owt1k0DbIHiZYFoU/lMlgBzFJ3yH5h9SHqQ OZyb7MTOWjvfAV9Bfn7wB9+h4ZDMlUPYS2rgX8a5HjfyLIqWjpa2r1evIZSHV8OH8NPuBgmI9t/x DzrIZrg4vUCNvaSbxPgD6CA4D1ZWetPh1Js1oU0Rcr7uER1NT75XZInCJouXygB8IahEMQoWotDp cFSUCFOrbNWhXkpIFdaTaXv7IAAAwIHVRROsJ8pO/wCJqApLSKOzcyRcSSOqsaqt1q2dMoUWnMZG WZT5UV6JemvLYYb4VTBRGw9TIURjgM4j8gQMV9/Xz2PTlPcx2N8rKty4Bs9r/LfZef8Aib8eOuZV MkbuNPSLIYzLjhGSNyQNh6sYpcGxTKzwK5grosRTDUeqoZmsVusTyeMsKtmSHZFmrYu2rYTXJ8r/ AIeGcE9kHh65rS0alRuM8XKPAwH3RCVX+/8A/gNuqTh2JZdh0/m1zLtEC+VWEE0+tmGCWyAVeXw2 FYAdPcHxbtTkiOpV/wAqQyZNXpsaT/0TB26ggD799B2DMrUZqDsVCs7UhqLdlJVA6kG27ldOARiy GUPWaK1BTK/h9hi9bp7hjakDgdcoQxZq8m8k9j/f9/Xz/gD/AFueK7aKgtCGkNnyaxclUlp7qdqf LgYXBypuIeFw2AxDQ7UcOY9nIFPqSq4VBZunNWZlg5aKS7nD4Du6A4+fAP2R23IJIpSjTBDG6I4l haNsfqo5DSb0aBYg60mWQ5WudkIeKVdRGHVFaNopyu28eoW9raNsUkJLU/ONDta+2pZB8eK5vC5k gyNr+yAyTGYV+wjzAJMajIrDKKMhBP1Ifs3zPgEPnB7MRkMo81mDCGzaPv8AwDwHVtLQ5RFy4djV fWMnOtomgCY9PpKe2B5UVhA3Itj7U42YMTB5hV248DmeywLRhmPez9OfAAHAdg68/qIaQ+mB0tRY Tr/rdKn6qGxr0/WpW4CZNFprCTTHtge8LImB4ZAy1AV/DANgiq74MWfuqQ8b97H9/wCrxyNXinSJ hVK2gYkp89kCKa/MiaZ6nMSlep4sWGPhmA+EMwwYNQ/lvw+MVdtn7Ib59+It/wAbdPgDklxMSLnE 8TiRo43xjaM1tMqYnDMh75bwOoJFkjkaRkkRkwjSaPKeIt7t1i4yypcbA9p56XtfsEcMnmADlnDc k9CUmxHfBrxEDnotTnpS3V9V7xaieyD0Nq7XwEbbFmm1dZ4O7JLsbP8Atv8Aigv3RhX9NaiKqvit 3zJhm4bxslOB6ffGheh6gikQWUmMBhbW3x77wQ4J4fANzBnF3z/e3gUE+AAAP38Jh3Q4XLU7JFsa YEG1oB3ZHMDWAsYrlzvnmcxf5hDuB8mD/wAlj0O1FtYwQyiyT3vmxw/v4DAB+/2Vqd0U6vcK3ikM iNSem58G3GvXkq7SHFi2Ha7I/nGQO4frOn1/3HT+Mi/Kd0UkJv8A9+ft/AAABI+GmlKwb6LnPSpu IkYKiQRS2Nxz2kJgmZHla6YY4tTqYiHwrbQOy+pLIhtEeLIbWVtRzk8HjjqOIR7gi1vDd2M8tJ8u zmS419qs6REWnKudUt8DLg/idTk9b03zMVt4beewWQnUDRQ6yjcJ4Thifxt1+AH34+A8/WRg1ANt gEtUAZJSYYGyHZ4ockeT1NPTalr080Q7QMIaGtrcwhxU9YAEFg89m2hmGnTlXG/PgD/7Dv74uBfT +6lqMdBc+uatGQ22R63r13LSz0r5V8TF+ZvC2nvg+YDxYLLnIYza2hZeXi0jiSj8Bt1BwAP2wAI1 4qrVpQUuyaWTXCroYuwo1e2g7ae5DYtNFXrzRYyIPD91IYd8HGFWA4QPh8ZfChNm+7OzxsG/vx/o 5FjbuNzvK7ySBu2R4wUyaSTuLbNjEYC9w8jnrFJuKpSJnKRQiEKzZVmF9QmhhGoXvajj2+erLL9b x23TvUrm+GDZ61bCJyzA2t63iMkpXXgMqHiyGLIZIbh8yCh/P3gnyho2z3NhDfPj/wC/n0EBpVg8 yjbwaVcW7INeJuMlTTx2rOmIqE0RcFcCnsER8b1BkDDzN4T1+2vh1mzbXhjjSVXO3PvA/wBAvwFJ 1nZHZHTJZ1JC0MmNihjVe2BzYepzVdyLRav9rgQ6HmWRMX4cCARno8xlJIe6DPd2N++G/n/fgPWn UoUB188OxkWnqVSriq2pC+H0Zh7jtSnLkXgLlDIMjJ3UmJ7B87h7a8GCZMpyZmR/NvADgG/7B59O oVxGyxSCR82UZLhH2YAl5LbDLLgYm6Jv46eFV1jKx+tgheXLhklC5R448XiO7I+Ca6h09806JBRb aJ7I7HosN2EuDUYDiZiHY6RUsWav1uHMVuYhsCG1T7AwVVsXxcXznZOE+A2B+4CeAHljqIIJ/wAy vbQTa3CLdVDW1tshPzpGzyrlE02U1CMG8cw3ggtvDbaClyQX+L6gGbIk1dx/YN/38+fAMhDq+wJe W7afAwfnYZDZIg/JrfhEzdJaurshGHDrf7J9HQ08FyR5Zyj4828j90at38Bv+B8+AAIJspx9Ocvv wxkFWyDDkeoqIj0/VZh3mNCJXr5Yy2P+G4h5gdg7qgV/e/Jq/OcLUSUmrcD/AL/l38QnyZywRpg6 udiExom4EykjjyLZJ53cguP2EXzYEwsygKyYI7agO5xzx27QCmrxy1mr9t8dVK/xNMGkHVnnY6ag ITVPWDs2sLghgXgt/MtgyKhj5iGH1H0m+V+nQoDAeuJbZxgvHawWOP8A7AMf0P3YslgtStJGo+Ba tY1dYWUtY04vmHut2FOi6fdKNSlIQAvDQqHMOKdNR21PwhMiNp7uTHAo8HPd3ffcAwYe+DAlCOnN bgZRK1cpVQE5zPYCWAl78kaAJaV+PxEzZ1vH5ljcfgPGFmM/jCYI394AHz4DfwCD7GxiRHDVPVd3 HraW0Or+0uNXhzAZ3cOBy/iOFgTFsxdifW69DgqQ9DnJ7NWaurE/uxtJwAbB5/fz/VmRXkjKn2ZB 2FpIshChkQgCOPGwSY4lzsZDtFaIEWOBhbl496J4pDFLGTJGYlZlkiawMyQoK3iVJN2GccmZh4xi h5ucSJNFhpLZZENDaIhi0LaltKuH+HDhzN4YJjU+Ve20DDGM4t8szYwlXhDn/wBAAbBW+HXcwNWa TYwEx8POmSVMwBmWgJQ4ibukVk+IH90+Gvw1VtXyE7k1ZiyhRZ837cBfj/uA4Af7AZRbAq6oZDHj ZIySrdTMd2jHD0P5YE8t2AYslPT3BPATPweeamRnZsRZNm82EeAADYN/wP7Bi37NFZ38Ust2N5wY kNXlfIzkeWyPkoS+NEMgY+GyGJjgtg8PgVzCJ2+hq/nUnwe/oID3AefODcFen/Jytt/T+xzx99nj 4x8m+s7csxzy7GesarHAV5PnP/bEijd9WWqBMtjUznrdfWY9hc4o1VNqZRs2pdQ7AoLCdp7xmTcG 5ktSq8FlOEY1Lb4EHT4t5xxxrO1MDKRyD1erFA9L7ifwq4RYbst2y6V09aYL4tPKktz9FtmpVXPK RK8WVPV6dTq/cTJcL6WJexsgGgqVprWFmISreArH1YhQZ63F9fxQvbB+K0uv6fFUf/iwLIZLOtAP GUzFhNThXtkOUpdjSpjBVdkMhiYtuCFy0h9P5MUV1lmBmwuni1D+GwW6f8+AT9iIce36Xs98tC2l sMGT7sqdfGoa9K5ldzY0IZjtu+WRD4ds5w8QqXmH7UMGebOf/wCvv3V1pi4Cqn0z8aWORLeNzVq4 sY7vHNn2HgjjqsWCKWYFo3WWSSCW0kjQUzBse7CxQoe6uOlLR9gSHdwGxNaWq7bc6pRt8yM5bHqc yxjxZovmyWCHcFbzKHcLAWwf5peA4wYU7Po+yGwhwB4Dr0aW3nm48OxoRjhOox8uwSQSdPbwwvnd BerlEZF9wDmA92LZGY8QGBtasBmnq0KvqAni7cJtXz+wYVF79VFS0ewKQzKx1c95glhWCHsiIPSX ZfYVuxpQmVFMEIi3yNbmEHEJt8A4h9zN0GLLwE+8b+A3/p8C7Qy2Mm4H01VUpgbuREvDJajEuZKs aXY13OA8OyJ8y1GQgY+v84cdsfODPPhDaP8AYD4BgAc+wRIYpJGeJ0WFqThs41AreheShhdx4vib pu0Y8tjWVUIdXz2ZWxfdj9NjHtuDHKmWdNww7aAB7yetGYvg81DW021VZtA5uTX7COLpJgt4FTKN D5s6fDp9bTyH8hV88HuYwXydZBm/9v4IH7/1yC7oMUijtXIw8k8pHq3qd4DrTRE/F9xpkWyGAzDW 7IW9wDnLMT+KmOcCygxZ4Sb/AH/wGH0EAziFbyIC+HM2XDG6b0jhJatzDteGHA+JlNnIrdbvktDm r8y1B6+eag4zte0DEZ4CGzbx5+3T/UPTen9bcnjOgRXBJtS7mtksIhbVY1/L5QerICr4j63DsiGh spBwsZttCBYxjuYLQ/6J2T3f/Pr+wAAC9tAmcxwviMVeTmiEPIrL888fBvoRuKzFVSZFQiUyJjJB G2FyNHbV7eFy76JyWuilTOaZ2i6CVyO+S/1WLh1LLHZLUHLB9QUVeA1LMAc8mMjhCTqrajyeB+YU GcX8Gk+DPYn18/sCD0oFcfDMlA6a52RKZKlzrId8XyG4WFDrloloaYY7qXBW4dk1IfDBtuPbkxyZ oVxgzhOybAfAef8AP9DY9LcM5wam1SG2RXr5nMlx1Otnl9dTygsSBKGPh/DDzFCr085/INRkYzFE MmzHEkIbOH9gPgD/AIDBV1uYOWM4TAzvnabxoGvVt3kNWlfURvD5SKQ0NCdaKGHDB1uY4Q/nr/Bw /fJYuRGZnjzZwCA8Af3/AGByRNDul5M0SFI8qx25PslrI3Vt22PPuHnqAxkRssXYzq6tmLbbxsUF Fe8G7PPNfHVjHBOTaCcmqrj6UlMcgCWy5MKQnXBSdiCYAk2KGmhon1tTYQHYzZsOPPw9WfHWAa0k j/RnZUFTWwgmPkwcrOudauWh67iEqyZNEumm/Myt2ZsVBlwAtY94iFd8H+hlKGs44mDAOSrhR6Rn GTJfLToUGKTzYa3lDYxhhOMGUWn5udA8gDsG0+RDkFvp6sgqLrcNXfiz/wCb1JEzKrCaFQQCBmTQ OPF8XWX4Hjqsd6tEMpQ8OexgbRAwLHSVMhajtV+o+HGPO75K2+yA+LJVb5/PT7AAnE9GeSgv+yef fkAAAAHwD91ajUbYF6ZofuXEakm4IGm/Srp7p+q08xETwB7CMUW7RT4bIHshbIOEI8P5VMWSfFxm xu92cHQf0+g7/jDvD5DpDT/fy5fCS7NWoyvhtOGKZPB1OHFTZabzAgnmIdkGGTzlaEFKueCvIt8Z lhH/ABcD4CA59USC/H35/aiKPbF2xE9civlJnoGdTgkOk50B37tVzYSa0cfmIafVZdlH4Tj1gPuJ hZRlfEmT9kkIDPsADHtFsABBBm0m7BAWQTTI8iRTxRJI8cUukjmmhEQj3IIxqEZ5SfJQKosnpCCV opZTIyVgHVGoo7WYkuu4SU4BoY4+Gy4SaAQF6ka7sI8nQwlPzxtXFu3unsOJcLuFy8ANw4W+nrfz DBBb36v54P6zzwmT/wA7UAAO0WwAPPw7jDj5rrMfLGQ4yfSMwbxdDo1XrLi5SspUoOP+h1u+ByKG jgV/4LgzYoavzlG3s3gf5Af/AGDYYdLX63SJAFDd3aNSeV2cteOBu0O73YBKMNoPj5X7IHhw+yfJ AdLEIFV85RmgqzLJyrgjs8Yb+BP7/wBaVs5aF0w85cyhpJqypqBZtwDciQ2GCiGw1zGW6v5LwOGn /VT1f1o8TGblFoE9jNhPP7AAqL/f2qJolWZQ+qk23QK0jmN5IxHDHHIWpss9pmxr0zYye76JllaO As6DLOliOUa0Y/alLgTfPJyFDiupjT2vslckQ+r7TdcFSPlv1j3CreZW5hTZHvVBXtDgHzZ4bI+L cwhZBxSYG2uYfGforzvaRVzw/cBP/Xz/ALL1gfLQMsCe+NDI/gbauB2s1fPEseYW0LUzz4yj3Cq2 Sq3C1HAw1dn56otjCfPHkZveyPGwf2DkHWRGtk0e2olaoK0xC5LbWNkafHc7pvsCwbTTpTY+NGm9 wDWQ+ImIge+NTYPsq0zD08vgwYSx4TV5vj79hx9+xxwmFMwbvOOHsFnT6uyTFhSbYMWr+TTD5V7Y 5NDJYD38x8p/j9qNWnjT/P54MGIauM8J4M+/L5/3590Ikkj1UqvppBDhDWsVs86zuJ4sRUkFjKbc 9fcvbi2+9DRoUK7yLMjsFjft3I+0JIGs1lRtcTXHcb6ku75Dj55XlGLRtqh69ZGuyK9ifW5SJX1o HlseI7qKBhP2d4AMCHBXBvA2fawdXBMcX7gL8AP47+f4hYbVfUCo30SBobBwrW6yNO6hw9KNMOE0 Poi4yyhP4hZC0yJ58PY/z8WtZZSZVCGf6X4m8PfABjhgwH2rW+le7DIDOlUEeJB60p+46nqd2s6v 5aeeKLyG5Mg9DQ7UqtwcCEMHPX60tRPJrLQLWSYPY0kHv78g7+fP4ACQ5alb3c6Pmwsjtf8AqCyX awk92PXAvGFh8UqlqWGwMi3ZCeyJ5CaqtvLYK33fV1cZj/Yz/wD/ABC/ADk242aSG1hkdmEg59c4 fTivyPU5vnjjqsXkgGcrnBEjKg1HIh/kWROcsu0qchhTcNl21XW46Wh1HcCQ5ZJtw1Ap8ZTz6rto gwvljPi9V9cuJCyLIrdPQsXCZBgONtU7MZuUboT+7VcD/YNg8/1aiv8Ag55cVUNXA36qlHZtYY9V qtsV6XchcuUeDsDg4p/zXDAOq7eeNmGYmhq9Z7GbSf09t/4C/n+lupkCAG3EkXKVAu/NS2po/bGv 5bIUV149Lhr4eq1uEYZN4araX3xHZBgxDVhjN/Wxzf8Aj/6fqeClvLXA4eqnJklWEBVf5gPTJhhM K4uW5VzZJBD2d8cFtgT2qAQUnhkZmZDaFl5d7RpN2N/v+ADABvwszyqzYP2O0qh1xwkfApgbPpxU cI/gsTlz02Mq0cYSNC4RQV04ztI/fI57ccclxWjlbdwrlJnKnQ7uU09jPKo4PlLZuzanau5DYhi3 NhlVLMIODIyIcN8sCHvzg3I/OSiuMJ+ESHZHQUHf+0WwbA5suv5DHV9naXz1bxpiGn3ZYV8w7Uj1 lDcj1T10erb8DrTIt8gQ7GBJ5A5W/JihRZ3zzZz9P2A+fwroYB02rkXw8GAu7tlATlOO8O5kdTDJ kqXXKvDX5lwcDQ/raqeYEPkm2PnBmbZAnsAAAAH7A/H5m1LIYNPrYk2/VWSNDu9erez5OcjqbHFi 3erxXzeDCHM+GP4O+L4E3MJ7piSJg3YJV3/f/wBgASR5JGjd5HZIrkhZGwuNCiGJgQ39KSRA98bl leCpGOPY3Iydt/UglFZZI2IYXYrLj4NAfPTC8IeKsgGdZBsa26iiUzEOSMy5kXTnEe3KEQ+Xs62y J63xJfrQHgTrPHtAzI5ve+0R9BAH/wBgQfkOxMwM6ATMqzuExQ7JEkHg9flrUfE3ECe7Pp8N8+Gh r8ydWmCkqzMHko+I3B/N0ef8A+vx/orX09nih+G1+NdryINT/MDIaSY5GLV16xlcPaExOW4b57rd 4AbBng1v6Gh2+MBmzaSjn/P/ALB1JWQ4U3FqdbPZTsMPXSYtGIQPUavr0xNQ69q9Dh/MMGIZiGnz XilnA81J/GeULLMc2NJOH0G3QH35gw6WZdzULK8jSwy3CFSO73MbZjnxjXaK7rPIrlgCBHjRMcc7 dTlHIYzF7GpbvPu47ePOXCraajTLpR74TMrOdu/GTaPskviQpsidUrFV4tkTtn1UTEMwnw508eB2 dGGInGUbuiDN7/v5/j+O/vxhMDNFaB2rSXcjhJqUoksjCYubOIqbIUtGXbQun0/gYcO+GGDtzPq9 8VbJeWZYV/YHj/597AH5B6JLIR7AApieZnh71D/W2xgcA7BLhnoqm0K/84YWw6fD8HP4HYzIzYoe LMTeDQT/ANj6+wb/ANOwpRZ+eQtrvdMN1Kep9AXtUC2HIXG4M8VsTQMMfDcA9VmWRwwaoFwdxoZR ZtCryazsmHgAC/8A9g6vdQSRtOiSYzGeOV1y+nktQAi8emOMEsY0eTfF7DCtrBOxI5MYwBIgPdn3 cu92z/5bo115+lLQMYLb2eKbat2OyIAn5mdX9ZGLQq8tY3dReDp4eFMmJ7IC08Ve2zphMYrlP3zE J9C/YNgP9ejTQh1EFsCmQzHcBLVRV42rrN5INsisodjWgvHnK4B7In1VDcFtvZAQFggTnD+l7MJg 6u2Sq/YAA56fP9IxkL3FlaNb+SkizEgPp/LscWx7BspXrHCr2m17tTw9POMRiwxfGAO1KU+pp+FF 8pKIwwHhj/y4Y1Fv/PcMcK+B09X4uSyjwGNDijYym4QwwdehtEVesaXSaeYWjBeHuDJOPp55qW7M eezdZkwfmweFugNgQf2AZWabblEm3g8qRSgeoa2sikilZIvtyCOMvknFaAJUlIv8iI5N+Luh45r4 6PMcuqxcgblXdDG2QmrZuwl8O7D7CMFALvSJRPIfNmBmSyF8O1PlXvmH+jhQn9JN7Hv/AO/8B6fB i3Fs8h17K/02yiTIw2BcGopgiQz132ahtE1fcNPdVskxDsD23Gy+NozNzwmT96udkf6/4A+/AACl xB6b7VV3Z3V2pA0u2pCJcgmV7X6o+RWhetD4fw6rT6rT/shwEQbbG3Puh9mOJITnAD7Bv/7BAp+j cwGIWEkZph2p+y63CNjwHQ2hT3RDs2UrB18xMQ3wwnuDJvzgpUdyZ5aOMs3m9jfkH2Qdg2AALDcn 3TKioayEhweL21ac+7n7hWJPTHWRIyQaR0jaF+e/TniMVYrHu5s3fAFWQO4LIsxuMNWa052m9k1D u1tRA7VcxBeuBElKb5p9DMKfcHJOH+CqW0G0GYRmZ7q/9fyiD7u+f3/6DI1/pDbKRF8SUnapbatV wZLNDw0NPEoZQoWAi6fI8k+yTN5VJ5A9jM+h8ZZvuxs5/T4B+AAD/UdM1EOCRYEyvmjJN3+G+SkV vZ8xfYUNDiu6vXKGPDrkOYn/AAHA4esEC1TNzVyjNvnv/wCfH8D/AE7BdoIBRHSa5KLdXAdS1Pkp bANcTAkxXP8AEzTdoMjAyWRW5gRyDYwOoD4OBSzFfUY84HAiSk+2/wD7/wCfBJ2jMSrA8MT7VyM8 SwJndetK8W5WJulFDyBY6jRxysZhMjojsiiS4n7cbyS5MfIoWfHnpb1Bp0sQU4XxmlAJsaxmKmLW uNmF0dkpuuWGualUOeQ3BkQjA9bnqR88jiBgzEqMGWpaHNQew4sHtgwMHTCHsAfKX3DgVGslVcPb anuBbuaOJfFfRG2RZVPp9VmIlqKD4oTDlL3hZcH3rMo+cGOBEk2DQPfnwA8/vz8q0dodE2QePaab ashPvh2bRJjJuaOvPdXoctEaE9guBw0xQ0N8IMliwP4eGpb2xCaOTWpjdqSD+ggD/Uk6Za3YIfTr UC4k204ZpJsiB3DlAkOm1ykIdymKvmLd2UnT8zupsI+2qBMdsxdNjKgtThPB/wBgP/sD8+WOV9Sw ek00rmVZdLJNFIXMMEUv1Bl08e/HJtRsEXHHuBbkEhE6QwSCEoJo4UhZp33I13tUQJNO+KXIu+SW rtxA53Ow1Q09Mnhx2bpzhLdhZRery1oPmTW/8QbO0UOLPoY+q5mjRjmBkCyOyzeQB4jFhoV7gZUa r9lwYN/P+wDDEBWSszKW225nC2imWTOtsPgWaKfPV/LW2ixnZ8KQyAcOnmA5i0JiqBIHuSDFl8fO MnElJ2PYD3/0C7FfvEOtCAEXpuznZbTYaS7tFqab3iI4dpROqBDDj0OyFtDhvloVXXL5sP0Zl05+ MOcJNgz+Hn9g+g05qevo/YsPm9saBDz0lb5RMcHCzQ8tXbJR6YQfDFwIVkTN4OdwLL2cmjC1dmJ+ EdvoJ/DHtF5+QyK67is6h67pI8HeiPdHk2FXx3NYJ9tV1UxVTSLSRViAckbPD2yUMsaAPbxx1uMI 8fKSzBTNvhJrcCBjahEcO1GJb5+Qruput1+YHrd8hmeH/AsA8qsnY1oF2YMB4mzZwAA9+fH9/Pm2 ZW6Hdy+TcsU+nMmzA63xe7O8HewXY1TuQsOwTKfodbcIa/alc6h8LpBp7yzofJhiO7G/dfAYvyC/ AN/PuYHwPKj21ArllSU/DVFW6mjWp8enIct8U3KuTCfcFVPgeq2QgGeDxD50MnyhoeUYHSYT6CAP 26/eAP8AUC2VPJbVutx7QBsipXLjZa6FUP8AL2Jod6lF2QQhob4Y/MD5OstPQ525vPKGW3+E9rt/ 7RAF8+/bAfMzJlG0ARHjdSrhfUeQ1hHIwbuz7grUMCCMWyNQKyq0Mwt0rj/CSL80bv8A28fNjpPr avHlL6qkZU1kT7LMKS8r2EBthTcL5KCbHlLfJEPTGnzOXw7G4+2qpis2amr4wswGE9njYAH7AA3+ 4Ec5p6PL5JXn17bSq7uDbLYJjU0JFqIbRplQyj4wVW4ODJvA9PeMbQqaxuM2Y+FGZm83vmwb+A/r 7qosN8dHdTJWDdOEa1EOzWSsmiyCW71XFPXIUPTE8O+Pkx8XHC4EgDgeBp5P2KDBiOECWjaiCA2A A/AAHVhMu2FOximdZdQTW1PDblZt8B2S2GH+JaLYRSxnz+G9wDzE+1CH5aYJ+mTtAsvmDy8nOE3Z pzfgB8AAPnwD8fUsdujBqSK8ImSJ42yxvcR0MZrAY7UcPk5Z9uNRsPVs4bmCll4kEYsOiP8Abnal jR9o4NdB5BfmpDAebT2c7OE6q9pRhrtIE4PkUSri4bgHfDFwUnM+HXJ+e+I8zckPjOGOyBEfE+g8 +fgAB+63GDAuvo8Olii3GajND1u7yGrOYNmlHhN8C8LP42+WS4Ibg+HLLX54N8GcDtEYznAng+An 19B4C/P3SHTyEh3uBP0t9zlJksxwC8HPGKvbO6IF3GAKfIdyDFDXxDIVvQJ4eBVRH5QV7MeKr7XO 2we3P+fW70/q7uxL4vn6frBD38ePB63XlepbOtjeJUXTg+HsbQZNQlbskyk7gwOHk++ONrNZq9yP LzvYQIcwfrd2AAg+fcsjR8CV8zWcakRyR1WO4tP7ucefIY/6UImDFCyMiuyJNG2ccmOAJU0vixY5 q/PSyHMhYquJzBB01EbSOtCeusz24D7yzMmaQdDg/LnzsxnBM6S4GlhulC80OSYhObnBBcwhPzGV XB+lTPgzBjOotvs+0KKIxa9s6qXGx2oYLh4YMCtY9aU/6stcjY5olLHHgdotS05lykZPFg80YXnK a7AGp0lVSQPpZwSgOfG3OlhYKHo61vHMeg0rofZyj4rkpoU1CwbroNyY8mlJokcmjwauhdfBr4HR 6YBlW0oBlMYFJrdos5t0yo8yyOEOB5904YtHvMWzFkB74ILdjPlP0PYzIsrKu0dzHirggRHPvwA/ sCCg0H1vR6rqNSHveVatwVdMV3Y3Ere1LCaEi1K5tpIcnNwYDFVzKfqtDq+ZBunznJ7fpto09LII IESQZ9Bfj4DgNRey2F35mZTANFuWm9StQDXsdTrfOQ7QbLgrA9sKaHcIdkWQ+Pkxwh78wAWowjM1 oFGbfDdXJKOAqLYUFCAHwHXYLzL8nwzCvPzgg1DmBGG6BrUwNhi0LkSBYqanp/G63tQwn8qbV9ta WQWs3JpzRibwb5sj93foPPj+J+kkmVAkUU2n7I5YhLHhHDIe1NhCT2RRqkeGQ9obLuoPkljdizum oLuzyBHrzjiDwaqmAPzya452zyAuLhkLjIdHPdOEiJaSt2aIU2/Cm5UpNmfDfLrpSY3p+OB6r0NV TyZN9KM2Ly6pLsDP+yEA/r7qfvBbuQ9YifKaKNCUDm5ykp1u1EiERaAtCQLtqk1+H23cA6Gvb4pO E9HXGZ5aKvFrJ027UmcPnz4ABv4EAATNyxNQFStkJcdz2quZaA2Spo/Gw6PMAxZYFymEGUwt8PD7 y8KQ8CDhlGZDKcZ//wAB9+8+bWpXavFs25rQAnpNbmUka75GdRo/TgtxSgipdnYHAx4eGnreDa3g Tjh2zV2gZb5zhITYH23ePoPgOjvUTx4zQpGskItV5vcx8hgY2wCg98beSRjzkCYqC8Tv2YiSOQ26 ycBkZa7MaFGznfhce7sh2BI1N3oM053TkoFelA6kptE0CnxIasUsKLV8weyQ3AOtmPmVyh2BPVoY zlDRyZIdtkBn/wD4A+YL7IptFfgZ5SwlIQ0OFosMdDvggW2toKplXrfAplPvtJhyHwQDgesbc+Lt CM8nDfa7gR8/UWwH9g6cFiU+yvkd81aRe5DhqMsitlMhnOGg+Y+OVcpCHaEMetw0/UJcIdgMI6Gn gKrhcZF05UCMctGrkl4AH8H4+AP7/gh6novTflaT2Se5NVXJJ6G23HU8MP2ncXKVbGwra+4GDNVW pMHQu0vaRHD8ZaBZMnanuExxAP2we4AB0lHiiSMaOZItO7rDGrQ7tTngxgmSPxxbeDY7RRtrxTtL K2ph3pnQ6xhuzRbenbGstp1uQURJGbw4piGJ6hhY9byrYhxQ2cpahIAd/wDDoVgO74MisKvUrgPh w1uyFtPcIYP9Jy3tnF7MRnjujSe//QefbCfARDpJfFzVIeXNRle+ZZLQs5wJDa3LYyk2vAMWGwTD PauH5lq7fIfwyYwosecN8JOf5IOwdNSZX+n9SILeVZa42zDIFS+QSs6PbBg8L1CYJsNhfE98MfMs CWqoaeenB0YYU3MY8JITDf8AYP8AMB1XsfVdPrF8ccsvJN2QhzLsiSVuwh8tkVnKXXL5NX5jgyVs t3ZV62jgXCBB3NGKDGZGB75sfgNg38B7MESlp2EnvhZygjmKQ7ePrIkSS+zPlWKZk8MMT0u2dII0 XshmjxG5EKyIv+R47vAe2+fNWLYQNgq+1a/au1TUcG18ytrDH065y+p2RujvxdkT4eCeh2qHXw6r hYFDgzFZMzRzjZNk4Rz4AfAbBiB6shV5yOkPr5WmUeSRtwXxqHofUhSV5L5aq1faTwsO4BzEzjd2 OBid9tVcFni4uzNjxN8439+9n7FB7vCqO2LF8Wxp1Tav0x1LyRPk2xU5IkwNlb/F1jOWD4QmVvDM Bw5APXClcCGD5MslLQRmbmu9nT4BBfgCDsB/pP61FO1FdofM0zxLOF1ibKsBin46QnlE1Tq+KZcN 4T/5wgY/n4FjTBn1fk3hAhx+AHz4DYPP5dQkWsnh0L6fcTT7OsemGmkE6SxS6aDa+piE4l2po9Um Z24nMD4TSSRw6tM30kE2ojmhDy5aRoSYmLwNW9Mrywy+mtJgQi7hZrK4jqyENPvC6SoIWBzn9VV7 sd2xwQ1sh2HTa5sJ8KLdX2o9h4a24L6f/wCn89OT2YYUQxayDCYm/v3t59+x6qKv1fYm1jcoXXvJ dI2cEU3C2obxEsgW5RBZ58HzA5hbMGGB82Gr21H+zbojM2+e7wfAc/8A2DqBru/Zb4YPHotwLdkS qxCL1H5x54SFuxnLs123YXBbW63mbgt7CvgXhkJjBfuT83+wfv2/89JLA1UA5MyHVVeobs4WUqku 4CeBaPYXV9hAShget42Rw9DH1u8YEG2DubMri7MrL6TsX9gQfAdOibuc1jeKqSdU8aot4CV/7zUn JykxTdoUnZ0kmEKot9lLZlbbeRZHxLmGOKGC42xAEZY7VEBmzNZvimGZENj+ZqimGRsnThZGcXeC xjS+Vu6kSgcenshik3zcFu1fAtQcmsi7PWBfZOk6uB7/AL9ifft/6shV8gxYJWyAzG4LeckAkB3e A95D5dbuXHj2zr/A6ffLIT2DfOYNuzvLPyhZ2PujqHR37tFsG/sHIN0fPOHnRPpu37+JIcWyQjAw JK2Qicoxqh8saZXxeHT8Rwl18HrmtdJ9tNT3gzNAtaJnOEhEb6CAAHz6/wBBMNkpd3sQwLSK3reZ ap9kiNFhTK/l88pGsgKuhp7IGfA74HT4dqQK/bZwazGZ8V3nfAlXJRz8RAT4AAg9RttWDBo1ljjR Jt2GIVR7DLtLHs33YhhNmQR24nIUVqLCFNl5IGgCUh3BEkojN3ee8AG4xKZUc6WBOOjwpI57FccL jmWWeSeL2on2QW3WK7i7kZB8Nx4fM2/CCBHviOtrBPi6yM5s7Ygz4Du6f38+AwmJi2KbdhFpFkak JjGtkiw9PT1dImVfdzvaB763g4MnJCHzm0e2g2TDaxazZmxmzbwA3/z6D59y2pDW4EdEsUoYqXTe hut1u9XpKq03xjYz3Q2AKaRWpiffFcOJD4CnWEBqrdnWVi42YmcC4b4AQWAAgAGBAfkKoAexCB5T D/4QdbxUs5bUyEyt9qZGgXU55XTyHzLU09/cOVNpCpYK2Mt/a9zB747c+QkE/sDAfQcdcTGJJTEd OXMz7uqkcYRgY4q617JLbJL7yo7lx6U+bOGljd0H086bXfIYzMkUpEdi9rdRicuSQOPPTszK7uy7 myk3KBcy3xKgUktIsk8Y2cDY1hSmh9H1uhuBhwhWDMVZ+oCe8snBkO0CexpKTaIPYH4+AAbByDJg +s4D5aiuBQ3ZVtBDN1OQh0/Itik/5s6LDV/DcHCZMcLA5xyACDtTc6a4MinDbsE59/1AH+pi0HCG UvQPYKunXZc1VU/GiMAEO8NlVtFcFqvF2QQT3DGx3CZy+4qHq+6UdPZv9TMUc39459wH32DpA5ty La5qYybQVxo3O4RJd2BVA0/Z0w8eXot3WQwJ8yq2SyIhGZakBPgTmTk3eUZ3Uq60auOcBP7Bz7f+ lqqxKgREwRA6iNbd9+WSUhZLG/t2FJwjxsGjnS07bhNjvkrJ/N4kVxx+T89RsdbS7fmQ3yvafsiY eAyWwwyMkiwltNAlYqu+EIb5gHhzE+H7788THlmFq7Nsft/sEAAP/QerErUz8brlI5tBILIYcVJT R6xv6v8AUJgmnlIohmG+4BDIxrbe/wCEEDZ9tKq1ijlEPH3SQgVIYEHkD8e56gL6UeOYJFf0yuAX e/QFX21aImwJuSPE8yQ3dDV1sfMT4a2tvhAPcUCv59jPiyM5RubxVxurXhB++nz9RP3R4UrN0tUg eisecyae7GshSbF8kSML0yuQIjUZFtQe+Mgfklbr7I1ASAHAOMZygtGWd7SXbDf37DAB+wgjqFIS J0TNirtLnv8AC27rtrt58b2mt/EfqnrQdwV3IPtbCPHGRayA7j3x2NuT7cj2m+jYWLvTNzEO2srJ fxpQOgSueTB6QnlFdTfMBBCYnmA7iHIB657f1NYzhwZ8V3kZ+pvYKif/AKDsHXG0FKTd9hFlLDsi ma0renLCshkPNDvCtraTzQY7qIbhpLZdJY/+wzpjMyq9X2+zAwZs2Dx7uoPgD+/pkwQa60MaaYGt yn38xS2TJs1gJODRZtwWN8TdHwen91E/jbBW/LWHnAdZWUPDjGGyd8Me/m/8+AcBYVZpfo+ZMsGg oeoen65zrsxkLaq8Kb5KaF485QyHw637qIdXmKdAsH8mjXk+C3nY3Y2k2oeAH+fHwGwHyZ5O8kY5 Y+jjE+5Vf1HhliGPxtM95d9UtrRY7J87Ts+7/wAvZx4x+d3PzkMAl92XbgOHqkumt7+1Sbwk2Qk1 iSrIheT4X+HXKtZr24sp8xiyOCehkZk7cALxtZN8aOTI4RJ8A/IP4iP4sHS3h2QHMr8NIF7I7baE rKQYJELNRAMVIodyQ/hzLUMahGRg4rAHgbGDjEYor3lWWybI8bA/H8H7YD5/qs24bO0roKlC0xen UMCF6jJdULWrZKuGu04tTrRZKcwubyyPywYxT9jHerED663ILA30jMPU7Ivr9fpPH8a/QgOGLWIJ epD+A8kLTVR2Q/8Ah9kiVsR6ZcFfh74+VlFfLIX4epDeEOt2Fwarpo+BeEPkwsXtmHCQm/279+wX 0BB6izTCWUNAgRpk2GR5RlBJe2XWV5rkUKcnUruWAQMR0mRIyyJE2TxbTTLVd6n33ZrdN8c4BPLX w5stLKWWtjW1jT9/zWRtYR5Kwo8RDcqvlq6uhr9bh9SCGZQ+H9y098v7c2Z8rCoEbAHsmwIP9AgP Y/S0PIFrZhqbVewm2nzwG2ncen8fEmBfHnI8+jzC2YmTEO8GSDPHnjhgmzFBbMsg7RwCHP7+A+/A G0vmXiuVMDaGnNw7nWWNN0j/AIKSPiCEMovFHyn+NzDAdxrdxDNTbeE+4kNGJ4q7MT/KJv8AEWwb 9z5Bfd3eSo7GqcOLumsfmOWSNXt45QWfGhDXnwWh8DmcwmB1/GxgLee1FuHd9oV+c8JdjSOfoM+f 2DYD4BaMQsgYu6F9uJ0js4REUrLlwRnxzzdfHTpRHJLEVk2nVAjptRUKqiTEkN3be4NVcEWbCWjL RzyvT9rV8ypIJchklOt4ZhPXpjk5LzkLfONuEzUIhw9n4kv1pOMM/PLkZll43vYvaoth2BBPn2oc uBgTe7VSgaZSXaKk0mw/4yTYDCYFyohSkWRg0xzHFD1CJ+KeqtqgB2fEXtbyMB0mb7VgAGID8uoJ /qHBp7YGmVLbVXodSw1y8iTvHsijNN7C+xRdZWhV80hW4cwYmLdf2ojga/Q4IfcxdDjGc4b3zgP/ AMAfVUS3KAR5aUm2UnKLtYWckREewQFb4mJL3pQsfmC/VZd8riuJY6JXNlJ9l1YhjGVX06WWynaT SHbYAFuYAQB8/UQAo4qMYkdJKtUwkie3bEqjCOR6yINE1WJoNzVzSRtaOBBlMCTUstxvRkeo4m/i KrQJGe5wRibBFcxmHks9PXKTjJ5RV5DX6TnODDMfGhhKxUMgGfIYhbML4dVbWCeDmcZK7ngDq7e0 fgIA+/HwHT4HMGnu0GhDqWBcxujRcO7OP1vYNsFk98TaR0llFsgt8kh2pC3ifUt4AdW/cx5Q9s2O rkk2c4C/W7sDAA2B/WoyQzNXzL4KIdFanLBuaNMvhVtOj2EP8XSIU4HwNDp98pOG4GK5rOwJ9jYD Hko0C7MOA+6OL9ihe/gN/rHdAtgV2yqyaGHW0mwbgNqafRuS3ryeUtB3cj34rcOSMi2wLaq21/dL UyorOL+jBAgRJBgH6ouAvwDwClmimktDqC8e7Mszx715GMlN3JNwdo5xXGxwb4ZhLplWU7MkI2YZ UbukHBCs4/pX3UO7OiARXdPEZlIWW+Hmh8mYUDd1MqTYQA6rq/tjtyetdNV4ZBbDsjgnrZDnH8UF tHJvY1Dq9ZGf6WvB8Agr4AAA3/o8bDFmV6PrGxophAcHxP0uqZjJDh8VtoTZZ+unBg09h6rvitw9 gVs1AbgA1zZHu0PjMzHO6JvYAAAB5/gOCqtRXsRyZGqwWOq4qRlBwhaNnHzFm97pSmLrl87PzA7I HfLgW7Usuv221JmLML2wmc+7vHIOQYoL8f6CnWRMUo4evmima37qw+Q2AHPV+WfMTzCruRiv9N+N bw63ML9cUD/9vDs5P6yyvGLsceEFBAffvAdGY2EkY1KpqEjhOnqVMJH07Y3G00DQyuaUczNNjdxi PJ81bzLkYht5PHJiD2LJFlgyJQxrNrFm+ORXMvZdW5NqHhzW/ouh2EwyFFOwzhGpsVYkCxljKmrY 45iiw513LZR5ZUyuZRiVXqqyeh1f1IhBV/VlIh8KnRQtfJOdKd/tS9mEmKDJeQ+IQit10VWWfAHp FsE2UwXVMM7LLsFlMcgO3Fj9gzJ0vOiFMo4UikUgQPBVblgFkYhDl8bnVxpqCiFB/aMKFVwhigKx xLSYxouZpEFKOfH+/VvJuOznXQAuxY83ySCfDD9/H5/PVjdPuq+0NOtlqt5Lk1Bs1omDdR0dqrh3 bbIOjIauKiYGWTG4IkKn/wCfHahwjIy2ZWHpRxmPpxwB4+kFhjhyBft6fBvGkys1hKrm39KUc+rN Zq+LHTnRYsKVQ9siD2AfHglWF1suQDeqy0CmDkSy8MaaWvU8Ou9emoQC9UB3H/mAsMRpvmZc9x00 rmpbcj1SgYxav2UPivQ65fKnirH54rdwQw5jjZv+F+tN4GDOUEyYP8Jo79/QNB1F4DjouRZFyj9Q Z6et23ajR3ILY21MIr3KJW6afVu0HCyLItR8/JFc1on74yM1Z/iAnzY2knF8+AAc/P8ATWMUchjE sweN9KzgLtXu7uJbufckOJzk7cu3tHQAMyQlsBn9RWD51sbAN9q1luAj8V83wVR8w4h0fpLY4qfW 54zYXxB6TeVX3ytPljFmgCydyN4ZEIx9qA3hS2IcnWb4UebMBhOEvHaI+fYH5+6D7oIODHHW7G1f DSQ233y2ki0Id8D69lngNZC3xwX1tlfHBPZHCZah6n3yj/8AS8XUAwHaIM3VYBCf8D4DHz+jTYJs udZhLO0y6cFFZzSSDYDOnUEkMSEKsb+HVgRH+qbep74d27x3MI1PDu0XZeFxvO+e+IRfr9AX39Cx PbC28vLpd3Q1Vinkq3agOTV1saX69VZFT9ka6bE0AtuEyt3wOn4L6G1IdoUs8TBlmPloec3t24Dy DsGf2DYACyRNEs7OHCGNYgsVxokssqxxadJ54nkTexmWUHCoypObAM24pEmKB3QTHGVlzjeooIz9 U2QutoGPjjJx9tnSYR7crShw+n2oHWTeWgBwf4hEC4VupzKb+WLivhBwshwTzCeQW8KlvD/cyv3y Znje0gGg8BQUHpD6fwZjuYyLlDgbae2ivQgm6Ji5Gr3hsoTEPMZCyO6kNk7gGMW0eP5ITwfLQWeD hLsSdgAAP7Bv6wV7YOaeKnsmpZWTW946eDo0S8WEH/KgG2hJSuUPgdbh7s+ZszUBcFJq2x54vWe+ BN7BgAB+3dg3/n1hbUfNUGaDGvnNquWzOHyx7tZAewg6bXImkdnHw3DSuHMU+wefHnoMMYTFq5N5 Bdr3Y4/bB+r91NN9TImqL6WNNMrvlMh9Cfbx9V5cfSkezlDjJtED1JM+0JhEuy6zXMmAdcP4ZJfc l5d+OA57S1+B8rG+Qa3b8dPnodPqWktDJVIp2QefGAs4NEVslFKrYLIquyA7KnkMLUgOF8TmQXwN WZ/728f/AJun37YHB3PcL4X8nNsat0ADPMSYgdJhh2wxEfBMp8W6/cOHww4ccyTj+m+eqp40ZV6u TJvHCeD+ffgHgOkbX9sW4LpujaM0+1WbT0fUU2u5DWMNqcsntFc7WBp/tuHY6TZC7B3UUkD+HJ83 O5Pcn4QJv78g8f2A/wBM3NIw1xPIwAN/aXc8DXFb0lPyNwlCMT1e78yMH0KrOR4RLFtkdPsax2dm s9YxKYGjaUDQH19PgMcV/DoIGdYoY4E1MSR7kMM0s0ru+zM0TSSPO0skjvgrMzS8WBX3G5QrySSh oS7JE77AxTuyAASzhVHmzl+BXQI+HNP9qkaS7QUO7MgbJCae3i7MmQkQwJ5sKAZhDkkMO+PjAt7C wgf6ZVxiyT2T22CokA+g8B6vI0K6/msB6/Qsz+F4Dnch23J1IdqinIWhomV+hmQ9bre/uE4Cnnnh k3N8KLOPCQhz8vHj7BsD8gdUVV2VfsKZDXD0NAzrBG3ZLtBqquRzw9yFXizG9P43DmQ+N8D4Gjwx gxXFszMDCG/9/L59+935+7B7YYzXBVdzK3Gds2GtxFcatsFsGKlOibGisjAYmQw9kTN4gnvo8xm4 HV7MT4Ukm/38AfP+AwLTQyymHPUOUjhbKT+0huR3HjRkOSZZ35NY4nzlwyaaNmlIgSN9RuYx6U/T xjIrZqpOV4rxZJ8dTDxQ9UV8vra5S6TetkXmAq2zVfVQNr8StgZSRcguHX5in4aHMhp5g421+eeH 0YTfFcY8nObJPaI/sB9+4Ev9PLU5MqvvQ1LoG5kFkVzAy7le+NSFPrxcDKKyykwe4rfeB8TyDI8W X9qp4YMFq6ws+aq7fz59+AH37pDrFLg8b7VWipRq3X1qVW2qZ/AxkNjIB1QFjr5yCIuPnJJm8I/b 6AEEMyyVaBgz6Sk7AAxQT+IDgPR7X9R1/p9rOwjVfOA18sF27xvGfXuoGJakr4loWNMIJ5in6r2e r0P84T50KsydoC/a1AjtjwE+gfiJ+fj4AjNu6qSRZkZFQ5Nec6zz00kE/jmGNdPKkn9TfcYJtXIs t/do4nV1zcSNGFx07IhARoDZ8yGeNxXaYkbnLFeKGwSIBiZAUqxQGp3yYsOtzGdg2Q7QTK9qXUZV a/DpNDDsrIwODW28DajBNGQ2gYT3vHYuA7/j/kANcu2LYsZgZMMqoKBr1ysJkl1+yTa/rIwLlWbY 0Wk19bcNN624Pi/sYFPnqqGs2YLKDBm91cbeAB9BAHz/AIBgEDBSPPQq9umparrcuB5t2PzhrAvX Yhn+/AGa4Q7IMOBh8YJljbe2o8xZvJoq+s3nhCSb+gn/AGPoL8f63WBIcGO2GrN1DmIySxmFsTgq hw9Th4tYWFKsaYwB1vuQyp7g4YkCFlhA6yTV7QswZ3R2Tf8A79wFBAP3S3CLgkmZ30V4ESWUbv8A zC+mgdJZo4skDSKH2sxajcFihoNi9OsyxSJXts2rXfN0eKHzzz1pQyCW0VncFXi9K9OHq5MWjp7M 3CejsRhpu5eTZTgnskyZT7JcFf1ZXJC0DyqhE1lXKPLzsnucAAPv2G/7/MXJyzTclZ0BtqsbYQuE Ns2p6Oh2eWuCkbaU/i2Qnvi3cHAw4+t3h8Xz1O3AsrO1s2x7HaX6oPn/AN/W2+WQBB8RnuFxpKRW 40QvmD5D5hQ8JAxWRwhVWYhQzHJHiewAZ3J0bi/gzeO+ef8AAb+f6MTC2ya3LQMVJKDv92X7c3cK 0bCsIeWW00ow7CtfMQ3BwcK3YJlOnh9LeM7X8GZtl4ThwHf0E+fPgOjcvuBHV44V8F5d3DLGyBgg 54vkWQP2egZrWR43y1LY1kLjf85pYyIul7h5I589LyoNbeqdJrC5NHFI0mOo0PcmNJV+0uxiLiTw s1oB7hMfbIm2Pdbitza2Halq4h4DCaEU5zVwMLz1gqI8AxP4YnrpumWy2C0GEiwWSSen6UUm+dQF /LdPu61FKab020C5AxagdPfU9g7Vnk+AEMDCauhrKzvZtJ39B/r4/v8A1Uu/JGoy1CCrZb4GGgWi vglTx87UUj/MQxdhAk5b+JW6G+TENxW1WB8Cq+dcnF4DN7B7Hv8AsAD260z5FF5XD56kkuteq/bZ IV1UDW7Y4npS9qMQ2T5kzUhdlwfzhzAhZZwxWZNo4yjfdkjYAADfv38+tFSNY5EO3uWzs/dnJ2Fn mm4q8hguBqmNnpsTb7OsvKLMsG2aSQIDcQdQO3bkVHFk5hSvbWXTgqO2I9crcOKBJKKeUrxSpyON rGyYjhzKvbalLezzE/TfMtRhcHgDo/8AndzSZPc3nsl/X3gEHwCD1MWQHjlBeSru7Ut39AfBruYr 12Hy+eWgjgVdkX1vjafMMkMLGn7DOcSfi3lmR7Rxw2DtEAt1BAeASV0WBDnqYeuU2nv8FoW34sQh 2cYSEM8Ud7Gpt94fDmae7Th8ENwKPnzpbNyfF5ZfuwRHAb+AX+QY7+bx9Tbo5L7gkBqx035wan9S FmyFugUehluWUiWM0J7hDcFuHT8OwHyuXzTfscPxbQU90qrrseEE/j/sEAg1htyISuac5NeISitc c5ZWfkVj83xHcSqVd8aKkmixEe3DLI9CrwzUVYyJuxdAkp+HdjGj2EBv3UIyf4QGSWq5UJK5ZPuT siLuSk2C+PD0nty3ObR/mCbM+Ifg9kN9ovsADgIDYEPRbRcjvV9faZFfVc2p1QJMZscAL5HXq3uS pWwXY4dgW4bhqcezC+YgqXEoKe87XzkmDCVcko+wAD4DwD90apcywLAX7ajZVD6kANyaewlDODg4 L93UOrgUjRvXKfX5hkxZA7gQXP8A1Iad5sxZZu6CysHLRN/7+P8A9/YGTVbAPYzmrTsjqudqlqpV 1IKbAnmKXtiYmyl3mVb2i+MlqU/T4fjYOyq/n0etvKy+f3s3+/gD/gMcerf6eW1aCH+76mHVaeFV qOLViVIuwWa2N0M3ncsDsqyxFeNFp5ZN2IxTMZO/UQHHFncqfdbEDE4i+WB6pmDv1HDD9RWaZtR2 fEevKuYXi2mpXXlur3J3i2M+L+nsx2rD7etwXxPbZzgzPPF0ZZB/i7z79bvPkEB1blBda5DItKPG RLtmRRVMMamj29qPgzXz0uEV+coTjDe73xUYT8/K1z4QQkysrMvn1C/SFOAzSRsOB3HFBAL59NAj AOBUYetGOpZNnSs6UWT3b5DDiBTdQgH4jAZW5i2thx61O5ghbwsrPa953yrnZJBgLdQT/Pum+jLF qBhdBFNQRKPVaadQUifXt5GRDi0HnfT6Bb8FDTe4S6Uqwc4YUvPUq4iMxNDWMFlIBmziPivv/H8X 0DhgeoVsXMauezUMZtuJtssIQDp4nSaWeQYm5IlTZsZhtxcV6ftcPmUptGlkyRp6Mok9SVZYoljf CmjlYBvKt2MDXy6L8zJ4fU7KgEiVkHnZkYa/tSvbAUzEuU7ngN8MGEPWAhocNgp85AcIHG+DK6uT Wt7SaueP+/n35gPz1BrUNjhp+odNSacJIYhkr1H1FJ7O2OAF8LRQNbjrUZGRkrdkr6Y1VLV98bOU JvlXVozHPNnPoPgN/Pn38jvlN2MLPoZS4Dbtq0D3JLDuGTcEszKV9Qp5otS8LIT5gfeF9wnf+oek JizwOrxnauru6JzYF9B8+/dAbQrw1LUoYTW1PJAZUNtrKv1Ua0S63PSpco9WxCJNhuEPj63ghuEB VmDCgsWs2YD8ID8//kAfsIrKrTTOe85zMf8AFRXt/VWebPnxx1A7SOqEIUOzBErpntRrlQBtcvPP C/H46FSFqXZPrPOSM0CbfK1DkogdJSa/pyZV4HT3KsaYAtSyO1a24D0NVPD3w4+cZpxXJ2Zzbwf/ AIFsHU8t5bRAYIZ60ANpTFymUm+a3mpNPqYfvcvSrkrcehh0NkuCyCHautKPPHHDjNNlPvDsD4Py ABUSD3dP+/ZltlPqRzHUZXw2T/ObsrmFrURWW11M7q6uZIIdkB4YeYwbG22BsdVrNmbWTKA3bzmH n9gxx2DsdZCnfCG+Cs0C7Eh42LUxh2VR8uWeTSwAXahAw+J7jDDuC3BgL8DGYs9m1fjJw3gbB/fj 6Dz4B0KhQyMomil+dQDt6hvaQzSd2cnJDviMuO0dX7M2llSRxjlG5E2BuxTWlZ1yaN0PFc/B63aF jKdemZ6ToVqWpVrATpHqUPV4kP8AKti0K52+yO9lkVsnuEz4GwfMrS8mnc2bZAmxgEH/ACYN/wAY 4eHrNXMae6Cv0abGpr4/qdoMd5WwpvmIynAPMOSQw6GH29kd5458p1PJoxQWLJo/CTd4VCfAfQQH UbDbcVwYBzVJDSd0AxpZA8YcC1kSuWafTxhPLh1uGHhp/FYCeB+Y87WLJk/u2+IOwf38/wBNqzFN 4codez812JWcxu0aXX8OZIlh022q9q9DW098quGYmVuvmGo8ngWrc3lXKcZ5sbCbA/8Ad33QX8Af jNPDJErFF0yRSMZS9auJ4ojFEVOJ+ojb6hjNHcX8aAscrUwsc2YvbmXBWY+yeNwM0d+NmsRRxlys 8DHnfX0O2L3um5zzHMUrmioYRheNQlnK8QxUrQ702muHbcPqoMUOnkEOxu+F007xmzHwWsPIT/Sv wADA/sHQQHzKzssXcEqtMk2BrRwJWEHzrODqbIrlPlVKyr+8UPdkx8T5jVUie2waG/iFKNBNZOJJ u7LU7RH7dPn6D3/oPqej3yLbB5Sl5xK2jyS23GQZHyt15k55XospDH7P/Jw2CGc89AWxjNugsYcC b0DP7BhsD959kD4bbXMyY5VVeVtJ+aepxhMWFk2RDDuYCZcj5ZA++Phsi2yODG8W2n3T2TWcbQ1G I3Bzf+4H5f8A8qi6jlo1jZncZIEAds/4yOfC1efI54+ehja8/TztDG3djhISua+DeHHPF3fFUQSt VbJtcBOanPWfp5pg56mhri56XbT85Z7tn4Zh6cV9bpNzpmmpkgZo+xpJSQ+hPWuZgtf2dihYQxub JwmGS+daazTbTsGukoecueqK/l1sCykOKuXox59Bz4AbOly38CNrJXzlrONHqUWwr3BT60aD3phZ mzLnrVlkOBQFZPBjs63jSxULKE0LMn9n7khPHvf6pc25FtiLPNDrH9RIOMIeOP8AiQPFDxtfv/x+ 6I2Sm4cCm7UuSjPjdqnDVpZqPW4FgYZloVLETVdPIOFbsjJcENwfAZ7iU4M8rHjFnm/+/j4DYD/d 3rjp/Vo8AV9wlVU4Eraba9Umyt3B8V1NPFLH8FtoB6f4HMW2RPq/GcBsACbWidZq5RmGPGyGznPj +wAN/QT/AGIalV8VstRSqDONhyiSDLMFeslkL0yr3yWrtHb/AJ4YfDCevmFVS4HVaezDBTQsozwE dTaOAqK3V/B+fgFRL+5LYENXywwuzKrSaBK3NW8tHyjzR3IKNEs9p9fE+q3wwhrX2Q4B1IQGpkwe Xyhyay8UmEq33+/fiLrnavSx6vRrFKJp0imik1Kx8R6qNbKwzpz2bgSZe41PDG9HCjrj1DxSvJF6 c0kMkKTDmSDcwBkiNCpBiCrfH/fpe2BbDQ+NCG+T6lGpOVTLb2nmEqnicDV2FNlbeYcK31CODHcE OdbVP21iyf8AqgFE2b7sbwYPAIPsffj+6vLEIXcLtmAxu2/Hsl/LVwkw6PiGMe7D4Mhp8xbqvZ/D zkPgcEwsrCG0LJMGk/RwADn2B/z/AE4KrF3gkVZDM3mYCZ1BanDZa6EMxV8uHUoGzSjQ4D4eMznk z+eUuBwLUt9GKK/sjhNk8A/IL8g/YOoxgIA1ePXtjIeyE3ya7cwJTE9SDgUOwhb4n4MjJM44HImA ajb4FqMExe1k1kHV+yAwB/EB/kf6ILcSiMI+oEJqSJ845NkjtjOK5O2fYlc0eeOaAxdpZw7abeXe BTCQb3KbaZNuVttn3JVr+evtqaalNIaIcBCPNtzZoH4mn8a7SKnZEMXbB4WtsBgxVbIybhNVR9wA XmYzLL4rk98djYRH3/YD4Df+qu5jIhJsOZPihySTF+NEMc2HpCHFfIjQAmEFuZ3UqvcODn6/5wh8 F5QzLIMI7pO//wBA8B8+aq9gOtoVfcAe+Hx/hoTtZHKNNMyRd3yqHiXI5PieYQ7UfGQPADgwDhPa v6oKExm9pBvf/wBgwP8An+2RWYeuVuHlWqyEq97YqV3MAExjEfH0XfO1mGBbZE+HD7fwzk4eeVbI ZifPCbNj+Lu7r8g4gPc/sDjKMVSUp2WyQZ5YxviFaePEfyY9gy4CPyb6DaVHkMIdEO3TOlf3iKWO ZaFnLbiEZPIv6j4w72FYlqNFS2DLSCj5UqGezlIvH1OAVezZkWxhPcaYnslqVXMQzA+1AYFwqU5L /F/aBnRwgTg78AQvoJ8+AxD7ouSGuauObhrmZD6QyG7CMMjVYHPKbq++dPoyG3p7IyOFVrjAtnG3 geExmGXIr1mT72uwR4PH+An/AD4AAW1dqy0mVPVVs1nYCNK1MXmGoxqEaaq4zYTEm1NSVnknM9Of QlVw5502PPejMHwkiyGu0Kz9Jz1hDCTiBNA1vMw9Prw/bpW9PuSvXrHETyUMC+Wgw4mGrUBZtj2g m2FSItlT0/eL4DzHANOgOCGdrd5t9pfFms/ChNg8+wbB4BUTLJbRxumX08McxX02ouGaPxuVYLCx Vryb4OVXWwWSZCd10RqB3KpSaNY4Gmo3fhas7tP7ACpum3yAUA04NM6hHZeR0kw0YbXbS+m3cYYD Fq2Rw9kYDFcz2CAqp4wX9GZtkSbRxAeA8+Aw6jbYOAxd2NVS03nXY+MbU/wx43JkVkYqUDqEpGxq 3YIbgnvidC42DqVw7jF2ZZ9u2e+f38AeX/PgEGST0+OZ0Z1jXwZDf3yUkjojwezg6nW9XxV6U0OM 9PMQ7shrbA+79aGHD+xqG+cmSDYRJqtBfj6CAPgEI+fakxbvy31OyHK0Jlfu1g0bSdI3RDarAiB6 QlacE2pTBC1JgeGHT1/g8BfunuqTWWhX5MDtIJjwHHYH7YD+wFGZI43lkffdppLDLjG1FAMwp3DV 8bcsfzllxiuTCUwIIn9IqGKDcA0kZ70YdtVkKPN3445rGjsAtNzM6BaBgI1JsONLq8PnXR8Mmr0i ecjFXw7gmMiIHX7JvB8wbQcPbEMWs2Yj2iku4M+AP+ft3YOrKg9OesDTzXkOr2KlDVZKWsZbrIxM T6mU+UWNYUWuLIHmE9kmslkWAZn0PYAA7cAzbBbyTBmzfsAQT5+ouP7AfqwRM6w3Z8zq60y2SNtR j0r05a7hScwzp8p+LyKnJfP4Le93At2qnsmD5AIU84vKxhg8Yg3bELx/2Xz9vHwHRJRdqQ21X706 vtVG8ZtY05Q1Xja3jsL5ckq7leuWQddtVoa38O0A7UBsCA1GMHkV3M5yECOwP9PAAMEHojLP2vgj bTqVWstQI15SOA8Y42c2o2ce0Y8gqwqmAd1yoFlEXfHwsqHcilr1AyAqRQjLEHIKgrWYtgwmLdI2 qk1+Gn2RaRZHJzHDgdXypepZXhuEwwnmO5K8tnKH4HBT1lmVqbWWZ4q43qHOb/UR/E+wcB6fGW0X BKB39WlaAVIPlHn9eYAK2nxLJKC7uA/MT0+q6fh1XqE3iEBT4Hwydv1fh94/F2CCA2AAAQPbqSjk FcoprZmLnVtZNg2dHs0xalYmWyt4tiiQJRbcK3WtPdwPkwc+Az3dqd+X1cWjIxzzdVvwD6Dv4B+Q ZhTeNQBm2KxKaeD2pBw1Sra2JRwOdHU5kpolOVc/cHxDcA9qfMBcfrT6ys8XebM9jaT58B4A+g8+ BoxqjmpR0DxSbaajEJIkscryO20bSTbVWfEbNWRJlSvaQxqVdkRo6yVI8R3VV9x/H/c/nqNkMFfp FR0/XL5W9tJNtVLhcVPtUJX+Y5Hl60HxPX+BmFuY4D+8SH/IzBgxoFvOx737/QUHYPPgIDNOalIF qZ2bTb3aIeAyLctfdrIR4kOpQMRNPQyDgtrnGw7At/AXp86GzbW0LKMctE3sewex8/sGIBz23adm PYvkVlWpZD3rCzvitNhuAYTWwquWFOrrFwEwxCeyUkn4bDQBDFlG1o02j+uynMcd/fgOIDFgALdT oNksFlyQM+YEodtyQdhR69PPBYxzJhPSjA9kW4eGzMGxnl9tBmRiML3NmeMTbs8b/wCAP+f6kOl0 2mjG7NqZNx5XDa+YNIMpmlKI+IuOLdEca0NuFIUtiufV6k6mWbKKKCDFIlZIY9uPmOKQEJkcaMmN WbAu+aCrh41euD5mzZw0wLT6uEp621B7YWxYuIhK7IwclcGRDDj/AJ2JA9BsgmT5Rtm9pJt4/Lr8 Aw58f6ZCVWbxUFiJ7G5IalnVLkm7YITbmsCG+AamLCzwdgT94re7FseHrmtB6F72YMV2gYM5s7Gz iCAXwDBv4BfPxrYPMAUcbFrRDW9PZlktGWGPTKvE0/jci9ckVPcEJwMcwZGAP89fnqsMn+G+S8J5 s8HwCCffsAGPUk2MludklV8fCUkxVSrJpwOqjSC9zKKJVuSMAdkZafmrY8wqgeeA3Dk74rrOxpJu k/7B+ngG66DFJYUkvPGEsk0um1C7nhoVifvojuVm/wANEWelaTUM8gkMMcTxxu6E/wAHATITihY4 GJ+O8Ub6XqO6A4CnkxWNPG3YZSTfKK3ANCnfB4DE5Q+DzD5ZFbmE8eng9PCf7Mm5tFXPKycSbs3x BxAb/sADoqKVPX5Q5DXANnJN/I7UD7b/AOCn0jVYt8LCyuoVfmzDFkQ3DGn4KkwPlHrZN5oe+Fl5 Bm9kObA++A+/dJ+s4an8cDm02kuwfVdMsiVHDZVgU6HPUO8FUMw4vmJin3DugYwn4Hq4DrBOz0Nm R8UnHtXivoJ5f2D9eqw9QWXrRXdLWnBI0j5AmtdJGHptiwl+AxJ4sTqCVYbev4XZY9jWnb5+FghL 8EJDaFrEbcH/ADJfqOHfZgYsV70+heXhaTGQFBWNZbUOGnW8QMu9tokjj35UfGPLGBNCVqruyK5S GMBdx3YVlha0KHLHnqUtCt0eVU9VvkCYyXBppSYtIh7mDq6RMq89LQ2hwX7UvihltPsget4vg/g9 V2+TV3xZsw53SN8+3/H9EHn0kwC6Pv23MkXRlhEq9rTmyn2xW5CQtprRw2+Idf1UYcKTT7U7qdlV 8DaiGjI2NyE7yRwgT6CfP93QD90X6jyi+GqLUhEi6e6L01JOq5bhvAdWklpli2Ok1yrsY9Ph6fET /lnrVcUPiicQeRiuh0+LNmbsSnjHgC+/AcAADr7mXYPlWZMsvWRk2RYbvDdq9V7O00vFYp6a+ahA ItbcGSGGuAOHT1tVUgAKdDqD8Dk98Nmwm/gAAAAg7A/HwaSXseOXU2UWPk72n1Mg4jWfT9ni3KHd OIL8G6EfaEjrggTMkAy7ckTsVEkccmL3XZk2IvgYiup3LsjLaIc2pc2yLjT5+kUbcaBT9hPDFSfD RIGmr4cGOq4bJZFV8wgtq+h1y+cZfcBay7hAnugsCDUXAdgfuq1ArUOWWj0+LPIY24MpDbacq/Uj Z1sQ8D2n2Imxe+C3VWL4Y5BMtRDsGf8AM3N80l6eifCau7Vc+Qd/t0/9BY7Tq0F0PWGbQdcVwbrG qhl11Rq3JWbW9T9+GikbuTrIXnGHRCe+uB9bVnysB7UGxeUL2GnMO12OKCwYY4797RzA8IbbZle6 QaHhqLJeenvsM4WRedLO8toVtR7lvDhD5ghoe4J6OBX/AMqLK0UaGYYc/h4ScD6EAAcBPn9/gCRS osmncTFJJImPsMcW2J2ievUCh4y3C0WU83wSF3iMoe4g8ccilauSW9pSb4ywfmvPxzRfFyJafbVP rdfSq+Nh4gck7h1RwaBMwWr0irnnAeYQzFD3YyJ63O4fq0BvhOzBbReSyD2Q3hsC/wABqLf+qozK 0shIh2Qxttem7CbVRbbHBqA1vLQwLkvVyL+n491E8OPZK5Ar4HBkeSf0b8omwhwAf/sG/gLdZliF MpXMymMDaNJ5RhTsJes6Xx7uhFUwCbdjhfFD0+nzHwf86BR4GcyIvPP97Vd5/wAABAHwHSZQ7caI FgMoaxryCVvFhg6ycALiPw7clNR9tFHxwZE+YyWQHT5kGevodjSyfF+TcHSQiTgAqIAAXwHgMZAN RLIsQR5EbLPKX1EyleULC+B2owJSuGLcqTlyAFTyQRZyDMumKxgJuRiMeI3jzXLDnFshdnjjpzGD FqUjHAhmNPoElK1LaeJdkVuStBsDFLGLJpRwp+rN4TzAcfMOAdQDaccEbi6usjP6JRsX3YMH5A4C fRoNPvjT7aGSr5R5kVbaahkSyLgznCnA4EpXp6pbUsEOtuFV7R8JqukhS1cGHlmaNzZuE73v4B+5 8/IL9sCZQx9oJF5w90h1LcyvMJMNgHkntk4Vyh1keKGB/beHW+pBcX3BqQ0+lniGMsxXKLDzgbw8 /j+vn/d5VGl3RFpewrk16krj73NaTYcgPYVbCTDm5O8Vyb+SLa24Pu3hzlLL7bj3fGC6u/ZHb/V7 wCD59ghj25NaqRxhJPp55b1JeOZ5IhGQpaaeVJEEAaVHiircjoyUSrjlLDpy8tudwCJl9SCMGPbR yrPG15NRSRvacgvFm3cQOkb8ZlViEdstqrewg6qYr8SHApq9Ywvh6fDfNnZCH8gvvkEwzE1coMFg zf8AYAC/v/791x7Qy5Riwt5Gksmr+ANivkw2iwoZQ8v7otj3BwT7Uh1tX62jto+Achs5MXthPHwg Q+g8Bxw3/oE1ENrAh2YBlNFhMtkZRhkXrILzGihn1Xi2xbRVPsCZvFVob4voljNvwHiGzDCnjNk7 o1Xif/ER8ABP9BJCyGhNrf5WzySSvabs12QeT2gTDFi/uQchDrdwZFtb842kN95MTKFCbz5tJ3/2 PgD+wdCI2Rknd5i8qK7ESUD+B7ft55+b6tmbZMZCAR1ShKkGRW9yS/UvHt7Ux7vOV9RqvZj5Xzwk T6HanYPAT4zFW9qLaew4y3Li9jJ9fzE9Dp+H/qNZaeeBoS0M3Tc9kSXYGggEI+AqPwB+YYJgOvtW lzXJPquMh5ucNlr7JM8xFPMMTyHMKgMIi2v4HEO0Lagw1mzUNXWVkHVwQ2cPgH8+AAe5/q3V4ab0 djZHZH5st2plU+EXh6HZ2l9smRSjZKPVXX7JwNwp+tx8wH3APckGe3+WJv8A8+Pvz9wDpV1Wh1/q CsgCZi1vGrdIG1uvcw1USCxhXcq9uSuUOwJhgxvENwQ9hp98eFsXRr5ue+BKSOPHaI/wF+8/0wvA 2cwkQ7+O86RYYYEYWM2yvJq5XGvm+FqrR+kRSJWA/AIAPwPwOrKaV9AtJ6iRV12Kul3FfrXM1E2a Fp6IoK9uamQ/qrIZ6QWIP0+m0apsQ+BJSBpCSYA52BTIAsZTARlthEaTyGWC3s+dUMzLap2gTzYi JQz/ABFb1H/SbBlLfWbbQ7ELjZwQLGh+tlEUsWUq8lSwMaDlJ3oKC8kkUlZCzlZLT61tqjGUBOzq 1FKoM1kAAnCrPHNZGvPPJ8H8dUZbJOPn9/8A86O2Uwhu4uyKlZ8mpc5kPah3en7hcbYLmIuqDT2V iw6vWrsTzEMOQcAfH3y8HyzGYpaFZjO6VopKP7n+7v790wtNa/Qd8SGRtuSybas7WvakZhpekhqu pocq0JZ6m08fMrfkjJDIGK5ss/2dhk0Yo0PSyDNJAQGfwfj+/wCwH+q60+ro9llbafAKeNJZsMld 0h2ya/d4ZSxrYaItkWBMfEQPagchDgvloKSPyZmV1d5t9HwtII8AH4Bv58/gAPz2ZWdoOS/RpRDy X/UsBaqBYbgsOyVaJL7jUNbVXw9ohreBhDX0+xgHaVVMbYrtBMZ5vfAB/wA+A+ggAWGUpHDBq5kC PHg23u+JYpTp2X6bUenqdoLIQY6MYJWSqBNNIktTaSA1WcDcxmwKYgrzIlHbeuzJu1suJit09kfA de6bnGwtnqADaNsNBICrFlsoUrJDimCEN8mJ5iEP2OBYAGCHZhavyYn2u2Q5wHYP38AAKbkujTI7 gz90Zd1rjgGh6oZSRYShp30zPYGTVCHFxgVWn3uhXwt4wwZ6BZQJOp+zMabGvGDrjg84H8GDFgwf 0F9CswfaljSK9QxbKMGu7haImwFZkH2FW6GebHIohj04OYQ94sCtziHxKctkxj5V+BM4E1Du2/7B wE/v/uH6d490JFduyaKJDUlcMdvSF5J5Cs1vgdxgZVq88ZE9btRaX3yxuPtpxb2xoaEZGeTYM3v4 ACAPgOA9FBpoocliWGDcueeGCleHVzySS6ggD+LPJF+7PbsY410DzM1ROrzuONx5B2ooURRqu2cY 4owqKuR8E8XQXsjLujNFjXKVMbQLRZCSWX8TBBeDgQOoUCLD2gtmPhh3AeYBqTAeRg61WYto4yd9 7RwAPz9+wANgf0Ok3+8yrhb+lah1Iwh6ewnMDxcewvmMqke0rhhxBluBPWx9WUfZdwHlWtyZNoV9 PIw5hshx9AfQT/H+jDVowWfpzmW0ByiSRXraHku6PM09vCQn6g4tDVffHb+7K3Mck+yI9aWAAOOD NUCHuYw4btFJBvx8+g/v+wVQOMmvhSltWjxocI1M1pcFXae08Dkr8tPps82U2ecGBkp+1HxPrcfj zxgbeN7Y0Pe2I92G0nDj78f/ANvn7llmnQCFYXhblZL3YF0jY7kqyKBIsjUuBSCTbxaxZXoTFCrE MZg6bEKtW3uT+psvamWM4jc4SSTEsMiMhc/fmW0T7MT7kXKTJQ219Ny7AhjWCkTFXIdsOSvZBBkf WSt8Jg8N4/g9kDCbTV7N2rNpGH//AHz9qEcpajJcFb2WH1ULbraF8aS2ExYVwXB/NK4kCrwyMN8o dPT5jA4b8vnkfkyMVaBn5ROWicfn4AfwAH8fYbONFbu7gSTcq2km5sqtyTvZDhZDhyQDSN86gmhw IOEOq0Mw+MGFxdwLL5JWaM0bmzbIknPAbBsAA/v69rJLIQJlMhuzLtfzbDwbMFuvV/8Ao2zXxDQ+ NuFqLbgtkJn5QgVWyLNltAtGWTmO9+58/wA+5B54ZAs0bl0RnwKMzrnlmVANWtY4nizdjkVyyNdi SN1dzuOqxSI23VmmLJTZeVoZD5+TwSTLkDlK/ZA9NwwieuEpKm8GENPbHBXsa2FdNZB5jjcPT2n1 eG36wB4OYUZhbQTZv2TkH/YOA9agaev20cA5qG7GyTJC+W4BzFkNkwXF54UcCDInokO1A4+Z5D2W 6zZvyYMwSQjsD/7C/AH7ojfK3bN0uWy21kf3YNpiksOlbOr28F7tK5Lya5cfhoa4tviGnh0cCwKU FkZeL8GWQnNjewPx9BQcD/gJ4GnlDymeiz4dXWdXyHGiWABZCBaYUsYTXNjQ2AzDmKEMw4MiOhp/ cUPWbNaHaBG3u7KTB/2DYAB8+pVVI21D+nGzl28NszrhQ+3PayPNLmWHC0AYy+ovxtOj5AVJwLpH +y77jTXQ4FdL05R94C1umdV/MAml20batqwk+t8lXLTALkw88Q+YfcGSqx/3yv7aOIf1dDJvJwIa 3w+/YbAv8+xX4GjzDZQ96Ld/TyQQlarhGiEDJ6MprZ75fKFvZ5hhOZJg+GqodgKVH2pxnlDNwf8A v4DwB9f2E/ZA4n0vQTgyJDu4WjbSlUqlLH2FfCOkGBaakPlyLa8yJ8N8Qoa+YVZ7ApHA/JtRn2be 3arjiDbu/wDH0E+A6orqM1GGIoNDyU2wls9aBgKJsgCk1ekWPF7eygNkOExwDmVswP2Oy08fhVay zC/cn5sJagDwHAfY+fNWklD4ineMxs45LyPW0K4q8X+T/wBOi2YoX3gH2krtd8sCcRwcR7q/wjnp 2UmDXwLJT6mGpkbZEpVsiXp3Q5iOw79K1YJspkHwk/khgwPhtYFP4rDJk1f8vgggQ3j/AP0FAwbV mA5hl0ST1fXBaEM87NsS0GrJHsMz5UQpw9hY7Hp+Hxtg4r/P1ynrKzqMKbmd7o84AYbAgn0HYD6T ZGR81BSOWu9p3ZQzRxtTsBqWqnpzdK5LJsVktB8D8krcywGNh4k8Mgzi6vj2OCf1Bv8AwF+Ae/Sx ZIdqGkPTHqHTeSJLHaZJhaE/Jju7gLTRLRV5hwD8wDmAw8M8AR6Hccxmt8pxjfcUlJeNgfj9un9/ PdHhLqJZJw/9GRV0bpEd52CBEmzRpIrpsWidbJbMNS0l2RI2Ss9yu8dkkePPYxDVllTcfb1dcfaD Q+A73ylx2tFwY5gReqe7O6GFkVL290lxRDB9PmLdkD7Irmen2X3I4yr/AJMB2iEdkbnx9+P8+fuv qWPoPKqu8rz1YXNGhHkOioket6lgS2R8PO4t8cOHp8N8hp9gGPgMClvCMslEOs8KrdglXPB9+/8A c/0gWw4tNDwttspwf7mPODawmLgVXBIQ4vcJNAvn5gW5lwByCGCgL7a8IbyTQ9sRqrChOcL78wPw D9/YBswD0v1LqAzraKDZJKr5jbEMWcNV3eG+Hl+K+Pjgnsdb2R4/524KfJFkYLfbM8I7JP8AT+IA /sB/rK0MepTELtuZt5dvsdOFtdMyjb03xuFITu9mQAQdPE7ws4d7zQqgYxPG8b4YyOkcst3RIVih HJBN9rydKLyzxgDmq9nP7Ux2oSd6fagNTrzJXNjS1eLaY+YtmK3mPlocqtqn7LeITyMV8dQow59J B7+A/QB4ADmKa3hpzod3nuwTnmcEwaGSGHs2ZYwtslFIXzA7IhzE9Ph1yAQICr+6C3n82BHa8LdQ T+wIIDfwF0jBRgY7AhrkaiBpKubC08YWBQ9EU+whhYvTghvhggyd7JjhDwMe2oBE+YTvLgZMl7gw nAfP/wCWOAHIeA9X1eYAocM2SSMGSnBzU+WDWRhyA1PUot8nmFuGt3Zjw+uQNP8Az2TjPA1nY/8A p4ABv/Aej3FEiiQPJtujq0a5I1GiFexd8WceD8c8W0e1W21PJnUO3LFjtyyR8xSou2ThZIaTIGji EDNXs4LbDxTGyx6rGGhkpcE7Cnr/AMx8illcpyBbM8wsgPAh/PYIAPtnwPjIwHib2M/wE/8A5b/G 5lkTHK1KZaCiTGPIaSyKbTNJamCycr6c3cXKmEQ92TGR83BwVa0r98R0Pa1er2as3g1hvngPoO/g OnkPB2e0GHBczXYJnd1ED8wAU/5gsWw1KrzB8MOtlw5j7xUv1Wk1kYU4N7G+1xzz/gMeQdV1Fw6b V6vs4zlXlf2SeslkrLhNhB2JkV9L9hLBRkYA76tl5iePh/AP6ecDLMTFoZNZO44OxzgH9P7/ALA5 gsiyqjojypgqpPV2ASSdvkgkUKF35HSo3+nl000g3EgfMm8K5Xgmm91f7V4N9SR2i/4pbYzq10R1 729qq8n5eq8lQIazflIYloTENgsdwT6rY7IwmA1Ng7cLdmPOHGWbGrsEkHUQAAA/VfPgIdwT2wC+ J+/WQShlE4lLaKBsgg7h00+JTWiGwLcMPjZEMgycS+Aq47YUKM3uk8338Bv4A/v/AESVNflQV7S9 2GbLfBrhfudV1ZVPp1p9fSWQCBiAXKHw98ZA8wwPshqQ3DTS8B1mzUN8ZsQZsGbww4CvgQF+8B66 9TGZaj5R9e2Mr1jonTw1wVdZ1P3xRtD8kPHpcWr09ftRk1OTFuEwYTp7gA42z8nuT9fCHNgt7nwA AAP9L0ciiYq6f3mMvEZ5UiJbci08oZZJZod3HMqQo7e0kjMU3URugEqS7V7MxWJcL8kR3k1RpZ21 rstvOXAhuEewSCquFHBts6fksgmt9nkO4er7QiXyUmcPqsw4Ia2wJ6rqHHz3gOTGPn2ZHNO3gP8A YL9v59+1PmLbk4PlSq9MkmUyHjFngk+PEN9pFzYUOm6T/nK3hmGP3VVJgUZy4Ms0YUGWY8JFopPA QL8APnkAAwH00fT3BDiHtRibYUaZxV/7PLd8csqtNcpdoXIhsDGyVWYEWqwQ523nka1EYn/TOyVc ER0E+g7AfAPz8AbLhRmmsDXa2dM6hFtb1StV+2wkGNK5hsuy+EKhotNoZGE3mC5nuA+2K3OOCOnL PA3vkx1KdXZ4XwCFv6+BX9gNpYmdcdQ7zah0STCtRu5D1SbKbWdKALe8f1ytUkjBURoEhoRqilaj NYqT3XjjwaF2eB0jqrMELQBtVXns52dp+QN3CjclfsJklFGGVbTg4TLsDuCfZFgMiqBHHvhs6xzw YM83diOAxP7AfPn+uM6LmVplkosDJkwyA03Ztfks5gLQ9+r2xkMOQfGTupVa3vEF8T+Kw/q6usjN 79/6Bfj/AOmPWmZR+WGIZ0oW7yT0DO2myDzJxOYhyl5ycltfDuAd8Tw9gTAaGwwHjDgzQ0bYDN75 +/gPf32CHkTBZ63K9PLgBJr0yqrglHJLbREhxRe1yk74fdSG+cwT+Wr75O2wZ9G/zNg/f/582LBS oUHRsAqmz7zW2h4Pv7qI8Y8gknoVijDxGRcNQjiR2ssVjQDNqAF1kOL5vpnVQwFDJRvHi88knHg+ 0tCTVY9I/iMlWFd28MCGHtSn9MQevzE7b0OuU95WbkaKz2M2kuyOA+gr+/8AUYlvAho08OC5mQ36 2mf8UBlzOk4GE7T7MqYUnv7JC0xvkS4HFwnTx4E37rNNqwwliFxxxAAQGOADAAAxVjI203Xy/DKA VW/iVXDVKWHMBx8St4vy9QTQnuExkQw7IYYDEECnVo1BifKEPnKObdgm/vyD/q774Xvw1R5euu0w 9xwNFFBAqHpqv6nD4zTNZTJNYV8BrkM/2PdiHakxjX8AaCv3S0p6yjq5R3rM3gEq8HjjsB7Fgxx6 AywiQFNNaR+quoEGz/HXuTUSQZySFu+RHasVyReCxMlLC31W4aji5O4I4E+67X2ZVQHfkRa1z55U uYBn+1dGKThiBckltL2AtjWCvU8o5CYtoGF4PVacYT7UX4bwevCfOmDPdXJvOyJJsGg9on5+AX51 ZzVJckd8mW1bQoa6vjHUpvBfrGGrxHCua5Xqlq/bzAcOyU+XHw2oCwPirDeXlDKec82cPgH4/sH0 DrSjxw9GWjTLlm5zahxckHqEM1JDX5a2hAZaa0Ia+nh1sOY7XzJ1tJ75OW7yrNXV9zqvsm7A0E+A t1A3/f8ApwPFN2QmvF5BWhbG1KmHkAqrvle1/YRg9/XnHvhp+EMz8w42sEBVZHlmF8mJ+ENnLdYD +G/7B1FRWnzZtyHZCxiaWvTnI3kU4Hztx2f0BQ6hZo42TB4nE0rFWFYyLt7bjzeFtY4vIWRXSBF3 ADn3RUpqgg8avSbIt1kYpk9GXq3fD0TUvXMz4fbd8MUmPMcuH2XagcZwNXJ4A975w/cffvvwDob0 92Q0Pl4LeaBoG9XDUjMdrC0/5NM0uvTNPoF3POcMhMuBPZLUmOEwHS1X1ps/fLFX1M6enjB28/v/ AIACA2BkNhRkrlPtrZrgW4R6Z/DLqQqV2q9IrdXPd7uXuD44Vun3xCIOEFSYJ6OYRbMaFf8AKf8A fwGL9jsHAT8CltD4UtyZqlqVwvUwxh0iwrQtQOHbDFjPhZ7irbBMmGGRwmXAh2MQr/Y8eMtHGd8x pQJ4AAv7+/bB1nMG5FGGLl5EMKTZYfU4yum1NIA2G7GIpUanw3HSm9zNBVZyt27PLKY1AWOF1heW NkW2/wCW6sLF2psY0bcUFnUS0513Q7WtrTgrvCTfLgitSlqhvjUJUF0Kr6CAqOZcIZpE0XeKwkN2 Vhd86zCAex80fMYnYTPhlDzE1y8cGctnXlV611CsyezNQHR0p6g5kqwrXyW9zFBayuyeNc/Rarrm m1tmfDA5uIFjeR/jxjkcpILf4jYtn15+9cfDMbvXIkZ0Y06gADVTACgBxwBh/wDrn/f8cwtqQabR wgg8j8HssXX681+fx07Fe1KTtBLMEKvPah6ZytN9tO+oBkDuGnBb1GVzTj2+TKfT8XCq0Kq+2+/E EOq1soTFvmqsmcq4JwhgAH0E/wA+39BsW2WxIp+zLCF1VbUmk0hkUkgfMZK/sO7bQi3GBih6vp98 vitgxghDVQNf2WqzFkm0Vf2zeLRCBKrfn6oX76DsGCxHyMyqhjU0TySTVavWAReX2RqV69h6gqvS LGtBbtBwrdbh1XMIMiO+af8AUtxtmxF2gss3a5JNnP3/AGBBAYr7IqdL1MT4afo8u52QLId3C7Cy O4zB5YOdtCnNRgHCv94W32biwfBgV++KrIs1mrtGnqzP7Fz/AGBBfufY9NEWDf3iRGQamN43QRDZ 87RYRxRgxw92UjEmmFKKNqV5CjtE+DrplUIYRLu+pBFSsdPPjIN3JI6XcIIy7bClfJCu7i+ZWDWM a1LLJEi1gXYn5DYYTQOJRomDvmY1vVZghDBqRHlS34u0GZG9zeGJ8+A3/f8ApwA8yl4qfqoozVeS bTxnm1sL+ntJDiQ9cnl4o5THCGYW9nDsC3BUvOVWL5RuYztdsmwfv+/8BwrqcOQ7GpevWhcdqlAn gQRhq9kp94lsiuepx8PKDhScSt4czh62cqXlsFOZfxezMxwJ+wPwDYH7kD91PbhHDV3cEANZz/ny mqri1kVXXshTuCxld3ixQ46H2fW3AOPMQYE9tVXCzBn5yRtkq524/wC58/h58AmHTqY63Js/qZGV 9z2SQytFJEyle+NqRnFplwPtsvfUsoYlEXchVnhQY3HKfScvzd09DHjnnqBr+jnjUOwp+n0XkIDg GZBrxZBi1LobPlRV5XtBPHp5hwMw7TT+6kDnhzjIyrxfbP8ArbYNgfj6D0mWBTvS0EusRll2p3gS ElbU2CsWQwWh2NaC80K8MhMDh/vg/nDan0thW9mbpgjEzgPznAffz/TrZNKi3d0xDtXTQn2QHFp9 J2E4WokkCxgCed5QGGwTLsQ08PiQ9qzT60nB0YYr85Z/Nu2B/gIDwHn2HIfJjk4AbBnuwRklDWRI rbhRCvJlcgWHSqLT18PM42tmXBkalK0OKzHknzzkyOEScAe/nz/AT/T0eWTb1CMjoEldXd9qePHa sDT0+efH9VccR7suMbLGd3M4THCuBJBqaBB/wZbX/bc/ddB+Y0HbBKU/PgadPmBVvS7Ep9br1fSN qV0hETYTA+U/dkxDWx/zrLT/AJz4MsxoaBn3bm2B/wDYP1AdbbIeKrq+0NLs/S+72QefDCkWj2pe VkRLIx0+qd8Sg6eYhmK3TzHzFX+RVUNmRimCys+E8Bv/AD4+e2Dpho9kGLBhodN1ynyVuVUtkXHZ BJw3YxSMqImyuPsggwhsnIFt4n8tOMhNH9uTA97dgewIOGAAAwH8a6smFXtDASqqVYSSNaPjO7wH iOHw5QFIaJRggyOC3DhzF8xYz44NrXthQZtmx/d+en+ffv4DqEYkiZLh0qRrJz78vafHaBgb93n9 dNkXMqsJymneR4z42628hXORNija1V1+LIr7RZjuDA2W5XN2fqC8luwl9wsJwr292jabGtBPq/vx W5hDrdghzkNPfJzJWVGtFoLKzR3Nt8X35BfgH9/UhyOyGWgDVRREGuFqzG1TaSVSp69DsYCJlAQ/ JOH2Qnp497sayl/GnXyshgvtmT3t2d0f2P8AnwABBPzy3VchyHp/PLOlPjbkoAlGziTRL37ESBQz HGzPdSGhkA848vqWzo3A8Rmx/wClfPtgQefdKpwp4HTbpnGf8ZtG0PWNOWw8JNPh+eK9jKdjckX+ SOFV2QYIB+5Y89+rMLQxjNVZv+gefILB+/n1LExjZrhEhdpY0h8GTsVGZr/oxrGg47zZtfHRSSqW 7O9B7X8ZeL7ear/U/wDnqwDIQbKgzMkXcirZFeiyf4v+WrxDAEW2WgVDkOYWpDmri+YR1K8KH5h5 Rosz8XY9q7dQX79/38+NR7oj1AQMGcow7KrdZFbie7Q0ww1XaAteTbGW1+t1u+JlPsjBMOVLX0+c YGeK84kpLscAP+D8ggD/AESKdmNlQTIYuVcBJ200niQlHA2E0XE4OdXidRjkhj1u+HCk2R8X0M5U pDuoYZyf3mjTqT4M+AxxAc+38+scyt6jXOYYZVP1dksaStxGjOs4OkBxcX7QHsB8UDCeYQx8OCeX 31Hrf752y3wI7ffgADgJ8AwIJ90kkQiDMXj2k09SZ7u8J/prngkUCRMt/vRIJq20ydcl6oaaeaeL RQRJLqZNSY1hG1DGzxQvIiyb0qRvngwUtLHt9xG5dBnLbQHM2Bqust31LpNkWrnP4mwEmHZAh8A2 gkAabZB9JoSFT4cwPWwbbaF0wnCzN0q9ZeXirjiT/X3/AOmlkMA9Xw+k6Rt/Jq6uLehskut945DT 9XptxvkV8sD5lkTWWt8WM42kOK7YMF85Jgzbsb9n5BP+f6GwH8Peayw7Qo0bW+JSsdPC9qwA21YC QHAFFP4odf8A2fZ6fT+5dgXxY0wpWSGriyZz32M/v4AB1iPT4cNp/wBJeoIzXqkqaRtStkcgD0nb DYY1Ld2LuF1vYH5IuzTehr8M4B55XKfzmr1es3o4ECG/PsGwb+g1FhkWWDYTVxy7aTlpoAdPtyTY 6YZwvozLuS39MtRyGHc3Di3pm3vptSsr6QxoZosYpdueKZFwrBllhaSN8+6wrdmPk302mRosTQ9D 1IaLaWA1LYbbdkanEdqs4ewp9ocsKRZnG7UD7xD4HBUhz4qhyayrUPZgzZKTNmz78gW6A8AA6ajR X8xoeFuuWlVXE+y6HSbusi1E+p0iq+42nur3xwYGRkT2RPWyDgDbU9DgzEYYhi+cvDt2u38/9fP9 U/MR2RtzDttJC3JAwK9kpEcw7J5bhsViV1eGPren0Nkhh2AxVfMICNMJjGl8/ZDZsG/e58+Aw+vm 0PsmruCqBSGS0q3SD1SrxAESX2wyftC7tVVNGN4fDDg4TfB8wso5DrMYUq9mWeE7IcAbB+h/z+vb UNIYlSHy0gRP5JIYtNGznkVnVgc4C1trvpCSMSSxuqC+BUa90acDnbkVHs+ccaF2CRbzBalMrGK7 3Abr1cG1xMr4lDj8lKPn3z8bdk3FPmfMOT6P7xGCWPKP1+knNgAc+Afv69KI+ZFkGGjh9bpNIraS 20dkmKfLTLkqWZYwGGvhw9kGENwIGJx7lqriMZnwpwbm1XY44gD6Dz4Bv4CxTwQKaLdRFAxSlhVd qhsGZTdhWAHqtXXkMo5RCljQ09cshEuCyDI58ONxA8jp4x5+8jAZs2bB+Ax8BsB+Hjvj5d0O5kOt KTGnhV5DbD1ENTKnxENWixJT4HH2p3ImMncCnoNluGniq+DM1Xoby81UkhOcH0G3QHPgADHpZ/kj kXuSTaxOUqE7lg/xyR3jQPdd3wFo5MjZnWVZDczPnJxWINFRXz7W54/NfmBr+QHrSYHlHluyEMpX rsWXyR5XEh+Glv5NwmJ8yYYh88eHxwPfMJ1BV5Tc6PCJJs4fAP2C/i/AD/XHbCdcjkt0/Q7kSpPO DIg1haA40jXpmK0CXxomL4cwHcHyG4B/n8tVVsmjVeVRhhwIb/YD/wB+wXz4APy70S1xfh83ZDSG m2H29+GBMMMw9KYU1X3AOthw8wwnmEbcFI4uIzy0bm8nHZJ5z/X78/H9/PyRgUjlA9nSmh2STy5n Rngg+KpBhcJLlQ3Mltw/nE9khsAexp6+BR5iysboMGfsZz3YAD9yD9VJFFNqBqJf6ErGNPPqbLQF 8v8A6U8i44/cTfFGNNIujm0kcaCGVEjdUGFxiWKbE+bG5DGwPGIUjnKwHo+n/SfbTZEocoHG5z4t kmEOSzh7vW5Rp36uf6w5JMZXDnAG8KzqtbJjBdX7Z7OxvwCCf+gnz/TORx+k+grgSYrk7f4IYa/t i/amorTPSO1i+0toJ/MFtD4eHT4YN8T3wHMJrNoIjyjWok/+P1FjgfwPr9FXyRQdBXYBPBiT/qcT IenivSGSHV4jIBilpR4O4Q/uBgOvw2rmFaTTCKTF93xiObdquBn/AO/nwHtd6qGAXYNZqoupaxjO 1aNVkbhnWov2bcFyHizmUZHCYHp+4HwOwIbVpaXwPk3kqLWXnvZaITj5/YNgP9outUkjlmRp0kSR I3YRdu3eVLEbbavnI02dLwuPOdI2DA7SZphnFINxO+SGJch2ZVmW+PB/xWKu2YDq88+adTL4qjal pskt0ijvlzSIkOxjynXNjIc9bre1LTMBx8OdZdgbHMJ4FFcYjg+Em9/QQHPj6Dbr8AganqOq9Oep QbSyakktYCuSJWEO09p8e2A/A7NiuVqD1unzETjdgVv2lcHyuXzkxQXtmyYfqf8AP7B0/SOZo5TQ mpRWZ5moayNTWc31lW+muvXFemgU1T9PIwDhgyPTIt4TJsDF8Ic3RmjB6Rt6COqOwYvwDn5/DDqu FuB6fqpLduOgeNmQ7v8Azie4MExoF7WeMMCf8xPhht4eMU9SrkMTWd093jZDewYe337gAC1ZXyoM MXZCxXCQY1yj22N/cKPgc9UI8GgdezTyyZqYprCbwWwRgMqxBBsXbcCubx5cyaUOWFVV+uGnhOt/ n9sdzrgcMWQ9V66e2fjcPTGHmVvPmNTavn+Sc5pu0NzwN72jn/oJ/gPn6dA7MFtsPODJpg2yC3YK JjmM4gkQ7QtCp3KKyXBvFJGE8wQquqzyeeazCyTKFMSZzZDZz3AH/fwPRUDbCESyFWwc2yP8A8Yr dTkKsNoiTGgC2WMBMMIf4bIoJ7BM4iQstH40TF7pvm9mznAT/AUE/h0+GSRdDlUdtO644EklylqV 8h74sIewhxVX2ELcjBC1IdVp9PhyEz5/LQe2VAUocYs/dvAvwB+P9RW2kGIsyOiRoe1Fu8i8tNj5 FDDmjyD5ORUdobWkhhfIg5O2GGOEdLlfN94xoWTfBeY0r6rKC3jTI7h1JqzbUUq9kMiHU7vUFS1K kPjkh2BW9bzS7g4YLc4FqQ+CtlCYvc1nhJsIjnz/AIDf+fdU6oeOHcih5DulqbeBvi07mK9r1flh wMotd+zp8yGt3wHwHuH++E/F5V0Pk2yWi7gwADYAAA+f9uys3Su8oxc10njzJamoKYSYVdPp+pxM zFN+LTdVkK35g4WQyMBi4tPA/TxVb4M+0LPBwiSko58B4DwGHTOjhl93ZK9FpjIOfCkwJLT7OTzI nhsqJY138PZJgcO+Mi/DBnk5SnB9PTNV74875shvn+AD/vwC4zKFCS4F5CGZo02kaQVmyozGOPOx YknXkcFqNAFjJeVGdscVCM2b7fG2ka0t4d2R4skcCuWon2Q0QKvrHKV31tuwpMq5gYbCA4Vk4OVS 6WhdSzCC24VvMT1tgD2NAr+f/Uz4rrOAMIk/ftg/fz/IF6rlBbQ8fKApLJcGa4Ru5FPslbiTCI0F nKUhkE+Ghhw8NxfDgIehvG2ExbQ875zbYwGwYgUHz6Cwlut7AsfT3WLHlU+S7cNVx17V6Tk0fbAa LcbDFsZ9cO6ifdlb8gWwd0/avJi8GdFBm0nwD8AfuA+A6CXSs49fHO32SyDTGVW6AkGKfs5orHng u2EPeCEP4bh8weYrm+F488ODMsq5RY2M5vZw+AAH/oL8f6VDCpd8QibaZ9iEZUVFEqzxH8gxySVZ BA7bce9cz750jdj5qvAybKVvnmSR/NqFtsrFadzEMzcmnuVUr5UrJFbyUSQ1LZivVsoCLHlf+cDh 0+HCITAdtMDaDm4DKvKclR7R2Tz/AOvaI/j1SfMIaf6bsw9VQuZjMulDQL5kWFVYdsDgZUSxgMOw A8OHajJMX2S1J5DTTBWxjMrq6MMtTA2cxAfl1+QQH2C10NkpdjsCww1l3lJJW/D48YqUwrsO142a +PjgQmLYeyON8D4lwIGHRkYpwYYjhEkIj93dg/r7DryStyh81ceDzlZedGW3yvX9tkNUNo/2m5Ab I42HhvhhwITK5nuM9qZEZZfPs3CcP3//AKH8OrgLTtOI80/iXviljzkYNthNxY8kkxYpIt+DaDiw nrTxwsUSRJM8GWWycNstkMOPcAOTxY69adJn/Fc08adE+wU9DfdcNG+k/bjQ7NNcqNe6Nz6YDZi4 dZHfFUDDqrjG0iCHrYVcDZctgj7lnzhU7NzvV6cPX6MnKzqm1hHQtfFRifOY6XQp4gDBzZyt6LTb lBOiyTOdMP8AqL1bKVXWSpOVbN/oK+hzX2pQLHFL0SWEmqrJT1BFeDChZ1nk0muLsU18KIWOKbOl bFbFLlsi6BoGhfHAvhseqxRFwvFFF5eaAF+3pq6eDFi6oNW9tVhquW6kojuFp5lV8BzdOFaQ5Ncq ZM/DIPcSq4YhDPuISprRug3CxZ3xCt8XveOKPvwEDhhifA9cdRlLEzUvT3Uu8XHQNS9/qy1AZ1YM EpbocXXrkmh19PcLhQ7UrceXuLb8YLJue6I2+JIQ3hv79sG/nwHTsh6g6ztpLs6tG3OW6rQ2q2lP UQyZO0uDRTensWhw8GT4dbp8wgHsatGDg4jk2BQmTwNu3+dRcBAb/j0kyhBwV3BVdwOntbGhs5bw sh2VE93MRD1OCnvug4Q0+yENwuAxBgL/ABUwMsy+MVl5B0m7Vd2DAHwFRAD/AOXTePTJIiiOY0jP FptQc9Q+1Dpo2EisDLL7VIzlOGZC+SSK7rxtIXR5cokl1ccku2c88SqQyQRmsWsKq+RZ6gUukz5S s74Ut+fzCa+SbDT2RbHsMOz3KwnKm+YXAhvl2Ib4wTJwEeBVbIZidoPhMmcNhN88/UIA/UT8/dWD stDELldB81ZiYWSMT5VfU/CAu+o6HE1AqTOrqEB8hWPinTIGNPNtYPbsIwZactFGKWoEC0qbYAQD BetzH/lQFXqvIWJftmaj3HNdo1bvcxjYLXJJ2Nsh06W2OStVa/hqErdbiVuRZUiCwIcGYsrNYFRt mA0rVEknD4A+fxfj9u9Kxo1E3IuVtTIuUNoqHbVPrde6Rxteo6nMrm7q9Q1dbTw8OHqEDzLA/o98 nWp+6I3B/Ngz+wH0DYMdgZNxHp5RPCiajUnEM/e2QQGFkobMjEDbmyfCm9Nr4qP05XSSJ89NCrkn tj9IVuLJzuxrlcsWKZAp6grptFHgPX0ebjedY1KHzbI+WPMODA779aAnGKtr5gOHpPh/w+IjwJxw WbMaNzZv87U/f9g/fzyn7czKHaKYv2AeSbClOyS2K+oSYObLUtoCvVzEW/yoH1IfMX98UrAgTvs3 KFkYc7ohNgwfkHE/jz7rsOHEOpRZKh21PoHJlTJKQR0orce7odjFWFDsat94T6Tsit3BPhVy2jx7 UZZkZoKExlVuwS7PvwAAf59j0q4YdLsZwGsbHp7dgK5T9b1lV+dYdgS7gAi6n36YvJ+8akK3hp+A SAPbbUMMxPi4smDNhOcP3AQGIABj0oJ9RYVZiiuyWkX8102meCfM1HJIhfLba9oLXNgmO2UVXhMk iK6szSiOO+HSWKWCPccxs6MquNrMMS2QBG7QzHStCg0Dcl2SZjQkmyysNAtDYtq1SiXyVD2dPqtw pPw9xe6kDcCe18GJnAgTfMd/PgN/Ab+NugcRYxAxQVgtSk7LjgELEKfmRxJhXaF5olB2BbDodqQ4 bAHsZ8cO3NbjBlYFBgtHSd8OH8bd/fz790bKCWwVphMY2Oh0hIsZ8G2a8NUOv75muRQSrvsPtWtL d2IbIvzEdD+ecT+5nPGYn/EO7cH/AH/YN/2BgnGDNd9Pb5LpamVt3zbmuNIr92yU+JDuS0FOrwAf mBgxT9qJzgHncfstUTyaNaDQsowNJ7JgwB8/wE/59+eHwlWJBjhOYS13neNMRQqqPFnz56GONWka yjZJkMGyxww4PA92XB/R454EI+ZV6RS9YZR6yJJltAhC2neGH0/lmRoV4j5FTyEOq0Ot3AxYC3O7 H2ZxsnZivaFG2/wnezh8AwbA+/fgDUT48ygrwW7uKIdtW00OBtejzA9XtYe2nITFTQ7BZEP+TfGC JBQ7gAgw6yMfMLLGWoEtE28AAGAABj7nz4pDzNK8Wq0+AApi/qZTXarl4OyOFfxIdjgVPX0mp7BZ Biq5kMwQD07Ar8CDcO5jQ0MzNgb2TDYEEAgn9/YD6+XxdoLifZCQ4kltVPWcpTKefBqeJMHkOJFl zE+yK3fEOYYYA5w9885MGFN0WSZw4Eq5HQQGL8vr5/f8c7ZzLK5TF2TBnWLZkOQDEo+T1hGsjkUc sAOLsVtRoYUDoqKgjjVHiltxiVUmNzjmbot4xNBuadmoy66Dd74uzKUg9o2Rpo1XNtOID4BeJf8A D4hpGoK2lsgHQ9Zlwe9fQ/r/APODLyxfEbfPNo78fPgEHwGB9GyDjY0avLIvh8o0bpXV0NSXrgM1 6rloiGr4Hk2iK/DQ7Hp9kXE9bB8fPPAd5KfefNpPOV9+AgT+PgMOOG0ZlS13Dt+1Q6iBiob+JHzF sPEZLGKcoKPg9kuBCp+7ENgMHFJfbTaftiuLJjDlXBO6gDj+wb+/P3T+c5ifF0v15V/bG0YZmsac bLYW63IXHW9oIf8ADketRPY0O7Fsun8kriliAEEYrNmfBbMMqs2k4f0Cgn9/AAOij242iiwmk3pI wzZblSCSKR5KoVmYlGN/vI1RYytKLaRBhwmZqkNBUB5vCjZ48jgfKlBi49lg63qrKMbbb4EavL4F VR3et+GiYtjQ8N4fIaeyL7KDrTto1IdZ1mUGdzAeyJO/4AD4A/iAAH+xXkL6ZIZDOnhDq6wl1VW3 cgSr22fPAYhS0JlgB63uDRnQ4cetg6lHUtBrZZGWhcoz+9vG/wDs/H0EB0YOCO4OwMbPq5wZE+yl sa73g1XYvu6eLQ7ZfSj5X9b2R2fD3AP+DP8AnvBhZKNCuTJo7vaIQHsB+ocH4/1I1PDXP4SIbRaC E2VW2LZJrHvc1OVESumiqIwFPgGGW+KHe4Z9asZsnzjnGGa46ceSn6++OGK/gAwfmD1MYMiPPLO0 2cjGOKOHHVq702zGNxqkmk3HUfdyOMLYQp3YooDt5wx7zzygxiAWZLYp2+V+Df6rlfLduVGGjjSm VailktGIRsH2Eqh3eGeV6RxV4fzA4dwMMg/Y7LH2W8B2ZmVyiMzb2bCYH3/YD4B+xx6cEy1Cjuh/ 4SvT6kyWgHZPj3ldi+j4WNV+wi+Ph5i24QzBDEGhsDbBDowxDFsyyD2R2/YNgP8AgOhtTrtbaLEa jTcyWQqlLr03xLQSdnYVsWUpyLaCGQmVW+GHBw4ejT6PPI5hGRrkV2ZZeLRCf7+/YEFg64xZVkaF fJd0NkN0y0WpGlr4epaHYYb4hNhSkbgIB2QPDDmLBZMIDh85bWdr7mebNVccQT+P37pZw74wqM4+ nzRZLkiM2YXcXDt/jYr3U9N4rlibsapOUdImeRBIRcb4YEvC1i5EyoNXp5eGzoI2HUZAyr5OVmgS WdYKTyyQNyQ/+o3xWhbITfmWQyw0/AH4FHZGas2j7OCCbJ+n0Hz/ALnk1bsRoqNbgPmdUqJWieFE yKrWx8RblJve4pMT3AxM09sjeQZHhDYJ7xVayzPmO5gwn3g+A8B9g60mChB3tAPXMWt5Om98PVdE aIedYBaYeKFmiVMIMj4+zTK0vhzkBPbZzITJi0N6WfCBPZ+58g4bAA6nrEugWZsGvMqoNPdXaezK 3UrC0WrXzxYXKQJa5KbcGEPDcFtkZCDhB7XW0c4yTaBb0TRzbtsfAX7+vt/fowYMSRmkFCJNncxj IBWJWzFydpwWvU55XDkYFBGAZU+pdoJ3kbFNtMfWmajUEeR3Y678k71x5UrQQW3yZbUtjuwaenoa TEthwviQ2ODkUa9+Q19bmLbJVcMcyQZ9gKX0blCGzDKruwIEBn/AYYIJ/wBySHSenNcsV2sEFqWJ Idl6eyTDdHbG+F4OUAtkqua3X4ZhkmbOnh/n88gshMYh7nUDw7JPn/v3gP0c1lunf23LC1SngLa+ z743Wr9RQ2n1OyFcC7gYq2QquGHMLcxgDqvH1FVWxm6CxjNve98+APz8A4CfwPocfU+Yrh1Vpn6e yTJAtpA7T0PYVPy8a5PCZUV8TzEPCGZmcw4GQ7VTLMWShSoFk5+UQdRH+Anz/IMOmjcjXcCvHIEY xo6ETrHGUxjEF92ORBbcX4GPQoyyPS2NtEDs026jSc5SO+CbOdDFcXuj3dvNutREyGLsx2cr4tpS zu1cntPMQ9N7ZuiakIbRDr8xW/Z+yIdfvnPGCf3IZhnF2as3h27XWofwt0AAQPvwCt+nNksDSrbk OAx3NJG5VAjROpBwloEuHQ/eOILDD1sPagdkuAeyUDZdwAUd8GDCiHxn/RMG/bD9gw3/AK46vT6b SAV/HqVuCiqTiXA7MNfWEh1eJmK7RU8VXmU8+IQeyFu7F9ktTj885/QaujewQIbR/wAu8+39+QUG XdO39l5Cqpz9K6SZgVvaFrmLsuan7jL2g0MIGIt4mENlWg5gcyBD9IPs5bWXjniMtfdklHPcBPr5 9+xAAKliSVFSR0KDyEOd2EDWe3G42kQVZ7y32U1whoyJIUQuKJLyFNuMY5uBg2dWLHb/AKm66jrg ZB6lYB4C+W02w3xwNiU/+JZHti1HJXsIpbVqML5T74tzDA5kqvtdAVWV5ZqvQ0ZZw3tJB7AfPn37 n3TOV3hPDJxLUEhquktqKDNPCRX7sNR2Ha7apECLQiH8Qm8MjJR4euHxPsyuQ6yzPiGsjLUdtPFo vH6AP9/Hw8oYrOql8O+Rc6nBuU1IEQheWcj1OyNAGnLaKGHCZDTnyG+EG9HQx9aPCG8rP8RlZrOD skm3jYH7gJ/+oAkfDbKpzHZSXHyQBrncncfNJUfLmWNKYZT4HT7sD6teN2oAhnAI+y4LIMrMpVyy jI9XO1oo4AAAP7/+/wAJcqioPYiqT+axAP68Hjni+elIFCu7i0XHI37bPHHzdV/2+enwvhw9QVWN /hy+PYWVnNlxq2TnD2xwVwRapQKenmafcENwshgMA55BtR/vNXq9ZjNkScDngF9BP/Qajre0C7Qb fhWXKAEsZ4eN3AQ69YC0woAXijkHT/sYeHyBkgz6/fAQcZ9oRsN8N/8ATDEAf2AA8dOanXaYUMV8 pE7ISdSLtZDDT4Fwsj5ttSlMDF4/s6fQ+ntbIMk4CwPlcviNjqLFvJM5dnNjh8/UR8+AwPn+kEuO ifFHtQEC7Sluy1tt4O7VK4d4KRA1Pciu+L6f8y1IbIOsgGfTwKoH3MWLszYzfe1Hvw+ggAHAQCC/ RxWTASB2xaNHTDOPwrhsmq+bFGuBZvi1X2ESbema8WxzxrC+LW7sfI4Hzd9EiWUsBIKOytXOd8OB qKq6Yr3nXgd389tbRt6GyB9ncPhtR6wJ+zLLy+K4z25sk7AAAYsGPgD7CqcolLiuqytUum/vwBmV K2VfQ9SoHD4tX2FYwswwOHL3xkcCHgbBUge5/Q3n+idj5B+uwdQLpbDgx6hENjyiRsMZZAneBkGB 5lP7DWVci1tfW+Np9kBuSHLar7s6tvNmY7mMBu2ynH4AvoPPt/A9ZIT1dj3gUUPDOW/JYXlPsKr0 fi/c0ohuLAHhzA5gwQh2MpD+KB1l55QzDPCb5sHtsG/9DGGeOEzLsu6afUlPfjll2ZUl1/ixHz28 dNm21mmWF96p3hjOOG4YggLe5sbzHHdX5qyE/pvKWJYKmt1KeatgXA4SWvnocjjcXTnp7aU1wr9D Q7gsjeCBiCPr88qmCbMUKYoxw2EduAn9/AAN/AAHZHFjuNjSmVZ1gctAqUQfZC3YAmnxcpsiyoY+ HW+GnuZVfJGo9R6kq2R3ftGr/BhEl2w8AggN/PgD6ZtmRXbQYDz4thSVtjSVKInuCTILGFcXXu67 fChw5sPmBg42p++cZ++POxhAlo8B2DBBx/f7UOPyEPR2eVzOCBQJkOpCdTGkVVcF6IetCWLKQ2AM tw63+Gvvhyyx7bPhs3KFcmsgwgT6CAP/AL/hh0yaCdtp4dLCsM8zQkqtSfZvMkv2btx2MTWC8kHp UcscSMjO5miQvKUbDKihUEd9eGo2eSeDfR5orr+9L4YLCzTIcbWKa1EkhorFUz2FPPRbCV9QMMgZ 8wYsghDeG2wHuctrDNQ7S8oyPV3gwADHYD76AAdJ9wU47OQMZp6jQiHcGTwjblu+N4cpUSLSK38O JyRkMJ7JXPMUOAno1Z4i3nY0k3SZwAgn0Hf/AL8g1XT6zF1nmKvcGGbT4thjV6v2TOpct/8Aea0+ lFtfZTCfDW2UgYqs8Q+dMswYhvjyMePuwNBAYgAHgen9Iug2kMfctNGoBjKzgjbX+NV2BbDI5Jol yV7IIJ8NbmUnDHrc5Sq+fOh1AzCijOzHAmN2I/AefbBv4DoYjqYmldVtJnV9O8BzkSAxxROA1LgZ xEhBo0VqjVk3wdVhKvA/OQdfFlCObF+D+KsfnrzA1h3rq3arkzpj2KVqfNxVkDkYV7pFU6Oi1eCj TvTKPer1FVKXYMorXlhE55mcVc0o3jFLwZ03JKTBw3Ex6IEfOvaFV16hkuU5ZogjateZDm4znnMr ahr6ryp6wr/0mxQaONWl5IvJKZ7BHejYhwkznSpk+KHKZhfcl0QICyYcDJzrUo0yKiDTf2lSIijO aXOlVR3ZFjkaN2xNnya6Xvany2r0ztwWdXQKx4JICxKoBrgAAUTx0j2FfXqtrunrfUgQyJYzZkao M+A1evJzPSZTCFM+un3ZfKAiUPNhkGGaZmOBpbYe58qwonprnOyqvWoq3XuX6lr13s0w6eq11Rf8 UzUJp/twGIkI6gw6jUKRJRE2uajOOmQsVdUB4OwuubVKUmhyZ3Ei4TsT8YeFEqrtFgC4L2sM0PLm 5M/Os65esdxHI4dg6pCFcMQwFvwGuwP0DXQxACRaAF6qzXFn8n9/vrzyvhnKaX6t0v2TSPpGKViX F/wvgF82E5zgohyLn23VCzuKxcILNyXmEyCMhCMAFRXFhE7IF5YxSjgB/rWcBcj5WdJt/d2k+kj9 64WvgqRg7A0NLUcPChUUVmKcpg9T3lB5h4euGRheCslCZ+PCsMjnKeALLkOo+Hj6cnLVMv1KuZnW daoif/UylnB9LqQ632uLg4ZfDDk8EEcnrY6I39jSsyqzRzaXbYqC0eWeWBItcqGWNXQvwOqfZyoh tWkt2a8a9TV0kng4rOnYqYzPB5ieZbxgUkX9amVyZuYxLYf1lAogp6FIMahJ2ZOGw8yYvy/RkenL wGq0gt9v/wDEAtWgsy4LlrGs/Tp5q5rnAaWsApWcUy9+hyW3dasAqPB+jALnN9fO5z1tVdkI4mLG UJ4oAOFwctdCwQmXnWdGpO2OTxHKw58MuGLD/MtnE+RZo9YSAPAA4XwK+B1fgOjZmQm/8WDLeXFu uxh0Xy78tehnS8M1dsg8uvsQs5IzUdmjC656UidjZQ9eAlnUflqMQZlMoUQbTISfJGQMI9YdMF/t hmo6jes8MtQzuoFmLKbziI5QIiQUkSxXOlZlfpuQPaI/qUa7L5HrzjJZAEZuSn5xHPzBkQLCTsfQ rejOs6W7u0+pyZmqd6yYmrq6smvA/wCnWuNVWNMVC3d4gC+U8158n/qevxBQhObQFm5/pnHIosCe QJkJZhEvVCXvQ81pZNe1SBtuPGjZWXND2yRVfVn5TY6rxANObsZxEcwZc5cITAWcwUitFlut21Mo n6jXwmTTrZRX1wMTxUlkCCBBUFqo7MFSD8kwR9cNWgl2qYtBDE4sAiFWqXNnCiOK1X2Wm51nTfEU jj3Lhi33LY5o+RdC6PPz1U/8h/2//Drj08V2GubT/dToyyiAj0q4TT1AHJyl6BIJCzo1yKLu9nvQ RWPQKkR5vqA+mcTUFPMzM7D1jVWfh65/qLNYhdaQyTsQzl1ppfTrcEAlsoZd1cA3yFw6Fi56YDLG CVTJhT0gwo7a874BAVYXr9c+AcIG48/OUFCPO9MkTkHxjDnWdU5P0+q5P8x/8gf+Olp7l/2/8J16 drS7AxbLKFBc0ip+iCna+myNmrJObCjeg5WitWTgif8AMuys6cn+tdWHe4XZ5FoXqXMa9yHHPEsG CpjPBCs2NTfPi41T/wAB/SjrNX55whaLw42wWz1phY2AnVKv62jItLJOREWv/QTijlDJn5dcruTn Sg+fkF8YGYbD7nsjAXGy86zpEABkjsX6qHn8i6P+o/PVt7JP3GwP7Bqwf0fkdVcql6MO/qxRhnp9 FaAIFNaVLBXcK1IMAcoqtFyUbW1OXJ6wxs0aYS8hctCvHYmvsSEfmG6/FRoIbBKVlT0j8PTm2cpU PM1FBKJsC5nGyHM1n1/X1lzvTjZDsu+kmyWRDMOLj6yRVSOAGeZlzmlZiHQ8zNP4m0sjKlZyKXWf 8AVgMzrOtOpASKB1AVtpUyXhsHYZJYo4tQyW6ahYNDpOmJMmpsk+t8m/ON+fz89UytHLJrr7bGny OyMefWkbIR5ceD6SOAQ5kyy9QuV7ZEnLaVPIXWHD1hHpRAYjfRiQxyJIUdFFsGUc9MaJnR7o6m9Y lx3jSw+zpfqUa2f7XXrlrV7c6rVYIBxMqanpSwsTCD6XQ162VwgciK6bkcSz+keeixiKyZdwcePB jsXp9UDOs6VIB9XEa5F0fkfxeD8dPj50Oqvmtpx+nUPiw/DLZxbyLNEdJj/hxMbrq10o3ERebEsZ IYtOtbW4IrZrqB6ZUJijxSxChcsjkGZkcjPjlhRYfYrCNalPNiZSRYHpywxixlluZwg09HbGdX8q ihutYnXz87xi2ka1rAyq/IG+HMnpacmY1aZsj/mscMaT5i2fKwO/Tlmg2oQFXXFezBqfgBYh2StQ 8r151nStP36PU59/r/f3ebvzfmhf5rpuoJjnUxkxk3eHb4269tfk9b82dbbDYo/OZ9QluNExqqSq vQwzj2XV86SePRR+ql5HuTNh20y47kzwSxtrh+rMdY7EGLhWsiMYwprKEqHqWrGaSaaVtRGqiw65 sLPlxhKyW01egUXRxKZXzPFFamVRjzGZWgGk9UEZoFIr9cToNfVCjrGUDU0ivirKs7OUjsBLNzs6 zqRABYgAAO7xx8p0pv8AinPycbPyeekJOqZUOimCnSvpmy1OvILq9jf1gZGcXmvgErqAnAjwuKPy FTPUoNhLeMr1Lw1bFQ3CKaJZlnc8MwlkwvQFZUKvjNJGl2ZNanNmL3Doh1328wH2nPVy5wMV0ak7 ISqdX1cj6lXJzBwOOGOZXqIlpmBOwR80LBkpDwnbm15bJnWdaGJyXk8SykfosYsiPwTQs/NC+lx+ 50+xkgDJ9jBdzEMvghbOIIIFmvJ6M12vjmm3UPXUSmrmulJw1FjoHptiSIbx8Gean0eASTK0eDzo QCLKTGNi9fqMjbAOJuaBIuYZsaxhXP8AVHM52Ho/cKp14dqHuNe9JA9NOk9Jz/Zti2UUmxCVhW61 W1odzdUbsQfyUsfmA8onOuBe9RqC1Iq8kvAaAXliRTTEih07BXzrOssYB1IcgF3giLuR3MVyxLN5 Yrk2JJNWaqz04E/T6Hk8GQD9BtnID8BqF15oX46SOqK0PSQS7/PjK3qZS9FIaXdPN8V8IVkiNBiD n6QeupTm4Sy8yWRcJyqXiAs0yypmcz4LDe5MLG7tww62To5iFEUssEa+0Q6V9YCQ7Na5c03UDbq3 kyo+UokFgeNkaIy1zTsrIWDioVHEMkhLnm6+mDT+BkL66wPEFvLF5U7IEmxmdZ1usnT6ZiSWbPJi bZqaKrJ5NWas8Wfz1kcAzoSBZu/37fP56YFZ+gZcFHWtcjGK2tlY3ILRzSPV2F1DhGWn7I0zVhbL bXZT04tEo3krpUk0T1Wd6BJwZOKI8YcDNTikiLiSzFZYzW0riTR9vjWZgz2I5Is2lo4VkMkHlGW1 8ZZRpLAmFlLe5DKBHmF8LDieoYLkRJqH6yeXnFiaWRIESsifnWdZk92m/USgfoApQH4A/HU1juul 1GLMtyMTixFm15NEWf2eeoW4dZ1zhE+6a+F+tUHgytE6fXw9IGANnLHCSAsNqeMDyCAaaP8AUKUi I2yyecWV1jLAiPkCRuQIjiBRNzGNd1aJUIl3UlpjlHzLUuErW0y1Nftjz1JmL5GW4t5DXkCjkxZo CxSWRTkLRGSkqhORG9C/lGsuaEi5UM7FG5kofIzrOsWpJTVRRoSkazR4opKotizSilFnk0Oeugiq wkyUNUMlZAGrVLq78/PVoNEv/Dg08anKU7kv3pYxx30OTMB9OUuwa3zMrNhxcyIU9GcQKttdtjWb m4SjEvIjSDrGTxEA8gOpgfSJUl1eBC86zrOu3HLKFUCSSuPvb8p++uPJHGXclEJLMSSqkk35Jr9D /p1//9k= "
24
-         y="0"
25
-         x="0"
26
-         id="image9"
27
-         height="260"
28
-         width="260" />
29
-    </pattern>
30
     <linearGradient
31
        id="linearGradient3841">
32
       <stop
33
@@ -130,16 +114,16 @@
34
      borderopacity="1.0"
35
      inkscape:pageopacity="0.0"
36
      inkscape:pageshadow="2"
37
-     inkscape:zoom="5.6"
38
-     inkscape:cx="100.80684"
39
-     inkscape:cy="53.200559"
40
+     inkscape:zoom="2.8"
41
+     inkscape:cx="-79.788339"
42
+     inkscape:cy="19.974291"
43
      inkscape:document-units="px"
44
      inkscape:current-layer="layer1"
45
      showgrid="false"
46
-     inkscape:window-width="1619"
47
-     inkscape:window-height="1026"
48
-     inkscape:window-x="61"
49
-     inkscape:window-y="24"
50
+     inkscape:window-width="1680"
51
+     inkscape:window-height="992"
52
+     inkscape:window-x="0"
53
+     inkscape:window-y="27"
54
      inkscape:window-maximized="1" />
55
   <metadata
56
      id="metadata7">
57
@@ -184,8 +168,8 @@
58
        ry="15.356024"
59
        transform="scale(-1,-1)" />
60
     <path
61
-       style="fill:#e2e2e2;fill-opacity:1;stroke:#e2e2e2;stroke-width:3.23991895;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:9.19999981;stroke-opacity:1;stroke-dasharray:none"
62
-       d="m 69.835908,947.50012 -31.578022,80.99798 31.805198,0.1799 c -1.8352,-1.8798 -7.200168,-5.5038 -8.40565,-10.9799 -0.306338,-6.1635 5.303808,-9.8583 10.904649,-13.1394 5.51455,-3.3559 -1.754507,-9.1504 -4.392504,-15.1517 -2.627643,-6.99028 4.786144,-11.82523 10.980704,-15.0875 6.402736,-3.8664 -1.788718,-9.29967 -3.204818,-14.14836 -1.56665,-7.91929 7.909128,-10.74156 11.849938,-12.71632 z"
63
+       style="fill:#e2e2e2;fill-opacity:1;stroke:#e2e2e2;stroke-width:3.23991895;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:9.19999981;stroke-dasharray:none;stroke-opacity:1"
64
+       d="m 71.835908,947.50012 -31.578022,80.99798 31.805198,0.1799 c -1.8352,-1.8798 -7.200168,-5.5038 -8.40565,-10.9799 -0.306338,-6.1635 5.303808,-9.8583 10.904649,-13.1394 5.51455,-3.3559 -1.754507,-9.1504 -4.392504,-15.1517 -2.627643,-6.99028 4.786144,-11.82523 10.980704,-15.0875 6.402736,-3.8664 -1.788718,-9.29967 -3.204818,-14.14836 -1.56665,-7.91929 7.909128,-10.74156 11.849938,-12.71632 z"
65
        id="path3815"
66
        inkscape:connector-curvature="0"
67
        sodipodi:nodetypes="cccccccccc" />
68
flowblade-1.4.tar.gz/flowblade-trunk/flowblade -> flowblade-1.8.tar.gz/flowblade-trunk/flowblade Changed
12
 
1
@@ -23,8 +23,8 @@
2
 import os
3
 import sys
4
 
5
-print "FLOWBLADE MOVIE EDITOR 1.4"
6
-print "--------------------------"
7
+print "FLOWBLADE MOVIE EDITOR repository 1.8"
8
+print "-------------------------------------"
9
 
10
 
11
 # Get launch script dir
12
flowblade-1.4.tar.gz/flowblade-trunk/setup.py -> flowblade-1.8.tar.gz/flowblade-trunk/setup.py Changed
19
 
1
@@ -33,7 +33,7 @@
2
 flowblade_package_data = ['res/filters/*.xml','res/filters/wipes/*','res/img/*',
3
                           'res/profiles/*','res/render/renderencoding.xml',
4
                           'res/patternproducer/*','res/help/*','locale/Flowblade/*',
5
-                          'res/proxyprofiles/*','res/darktheme/*','launch/*']
6
+                          'res/proxyprofiles/*','res/darktheme/*','launch/*','res/gmic/*']
7
 
8
 locale_files = []
9
 for filepath in glob.glob("Flowblade/locale/*/LC_MESSAGES/*"):
10
@@ -41,7 +41,7 @@
11
     locale_files.append(filepath)
12
 
13
 setup(  name='flowblade',
14
-        version='1.4.0',
15
+        version='1.8.0',
16
         author='Janne Liljeblad',
17
         author_email='janne.liljeblad at gmail dot com',
18
         description='Non-linear video editor',
19