3v324v23 commited on
Commit
a29865d
·
1 Parent(s): 63c3641

Auto-deploy from GitHub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. app.py +117 -48
  2. space/app.py +117 -48
  3. space/space/app.py +117 -48
  4. space/space/space/app.py +117 -48
  5. space/space/space/space/app.py +117 -48
  6. space/space/space/space/space/app.py +117 -48
  7. space/space/space/space/space/space/app.py +117 -48
  8. space/space/space/space/space/space/space/app.py +117 -48
  9. space/space/space/space/space/space/space/space/app.py +117 -48
  10. space/space/space/space/space/space/space/space/space/app.py +117 -48
  11. space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  12. space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  13. space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  14. space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  15. space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  16. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  17. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  18. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  19. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  20. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  21. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  22. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  23. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  24. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  25. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  26. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  27. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  28. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  29. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  30. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py +117 -48
  31. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10003-10041.md +47 -0
  32. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143 (C06932208).md +147 -0
  33. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143.md +68 -0
  34. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10156.md +55 -0
  35. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10213.md +206 -0
  36. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10005-10321.md +82 -0
  37. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10006-10247.md +145 -0
  38. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10007-10345.md +326 -0
  39. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10021.md +192 -0
  40. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10222.md +72 -0
  41. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10022.md +102 -0
  42. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10024.md +29 -0
  43. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10035.md +208 -0
  44. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10076.md +180 -0
  45. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10078.md +199 -0
  46. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10079.md +61 -0
  47. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10014-10051.md +56 -0
  48. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10014-10064.md +149 -0
  49. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10016-10021.md +74 -0
  50. space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10023-10087.md +907 -0
app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/app.py CHANGED
@@ -38,7 +38,7 @@ def wrap_label(label, max_length=15):
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
- """Generate mind map optimized for Hugging Face Spaces"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
@@ -46,92 +46,145 @@ def generate_high_res_mindmap(text):
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
- # Create temporary directory (works better in Spaces than fixed paths)
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
- # Simplified graph creation that's more likely to work in Spaces
55
  G = pgv.AGraph(
56
  directed=True,
57
- rankdir="TB",
58
  bgcolor="white",
59
- fontname="Helvetica",
60
- splines="ortho"
 
 
 
 
 
 
 
 
61
  )
62
 
63
- # Simplified node styling
64
  G.node_attr.update({
65
- "fontsize": "12",
 
66
  "shape": "box",
67
  "style": "rounded,filled",
68
  "fillcolor": "#E1F5FE",
69
  "color": "#0288D1",
 
 
 
 
70
  })
71
 
72
- # Simplified edge styling
73
  G.edge_attr.update({
74
- "color": "#757575",
75
- "penwidth": "1.5",
 
 
 
 
76
  })
77
 
78
- # Add central node
79
- G.add_node("DOCUMENT",
80
- shape="ellipse",
81
- fillcolor="#4FC3F7",
82
- fontsize="14")
 
 
 
83
 
84
- # Add entities with simplified structure
85
  max_categories = 5
86
- max_entities = 10
87
 
88
  for cat_idx, (category, values) in enumerate(entities.items()):
89
  if cat_idx >= max_categories:
90
  break
91
 
 
92
  cat_node = f"CAT_{cat_idx}"
93
- G.add_node(cat_node, label=wrap_label(category, 15))
94
- G.add_edge("DOCUMENT", cat_node)
 
 
 
95
 
96
- for ent_idx, value in enumerate(values[:max_entities]):
97
- ent_node = f"ENT_{cat_idx}_{ent_idx}"
98
- G.add_node(ent_node, label=wrap_label(value, 12))
99
- G.add_edge(cat_node, ent_node)
100
 
101
- # Try multiple layout engines (dot is most reliable)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  for engine in ['dot', 'neato', 'sfdp']:
103
  try:
104
- G.draw(output_path,
105
- format="png",
106
- prog=engine)
 
107
  print(f"Successfully generated with {engine}")
108
- break
 
 
 
 
109
  except Exception as e:
110
  print(f"Layout engine {engine} failed: {str(e)}")
111
  continue
112
- else:
113
- raise RuntimeError("All layout engines failed")
114
 
115
- # Verify the file was created
116
- if not os.path.exists(output_path):
117
- raise FileNotFoundError("Mind map file was not generated")
118
-
119
- return output_path
120
 
121
  except Exception as e:
122
  print(f"Mind map generation failed: {str(e)}")
123
- # Return a placeholder image or None
124
- placeholder_path = os.path.join(temp_dir, "placeholder.png")
125
- if not os.path.exists(placeholder_path):
126
- # Create simple placeholder
127
  import matplotlib.pyplot as plt
128
- fig, ax = plt.subplots(figsize=(10, 10))
129
- ax.text(0.5, 0.5, "Mind Map Unavailable\n(Error: {})".format(str(e)),
130
- ha='center', va='center')
 
131
  plt.axis('off')
132
- plt.savefig(placeholder_path, bbox_inches='tight', pad_inches=0.1)
 
133
  plt.close()
134
- return placeholder_path
 
 
135
  @app.post("/summarize")
136
  def summarize_text(request: TextRequest):
137
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
@@ -252,11 +305,27 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
252
  return None
253
 
254
  mindmap_btn.click(
255
- fn=display_mindmap,
256
- inputs=full_doc_text,
257
- outputs=output_mindmap
 
 
258
  )
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if __name__ == "__main__":
261
  iface.launch(
262
  server_name="0.0.0.0",
 
38
 
39
  return "\\n".join(lines)
40
  def generate_high_res_mindmap(text):
41
+ """Generate high-quality mind map with improved visibility"""
42
  try:
43
  # Verify we have entities to visualize
44
  entities = extract_entities(text)
 
46
  print("No entities found to generate mind map")
47
  return None
48
 
49
+ # Create temporary directory
50
  temp_dir = "/tmp/mindmaps"
51
  os.makedirs(temp_dir, exist_ok=True)
52
  output_path = os.path.join(temp_dir, "mindmap.png")
53
 
54
+ # Create graph with optimized settings
55
  G = pgv.AGraph(
56
  directed=True,
57
+ rankdir="TB", # Top-to-bottom layout
58
  bgcolor="white",
59
+ fontname="Arial", # More readable font
60
+ splines="ortho", # Straight lines
61
+ overlap="false",
62
+ concentrate="true",
63
+ ratio="compress",
64
+ size="50,50", # Larger canvas
65
+ dpi="300", # Higher resolution
66
+ pad="1.0",
67
+ nodesep="1.2", # More space between nodes
68
+ ranksep="1.5" # More vertical space
69
  )
70
 
71
+ # Enhanced node styling for better visibility
72
  G.node_attr.update({
73
+ "fontsize": "24", # Larger font
74
+ "fontname": "Arial Bold",
75
  "shape": "box",
76
  "style": "rounded,filled",
77
  "fillcolor": "#E1F5FE",
78
  "color": "#0288D1",
79
+ "height": "0.8",
80
+ "width": "2.0",
81
+ "penwidth": "2.0",
82
+ "margin": "0.3,0.1" # Better text padding
83
  })
84
 
85
+ # Enhanced edge styling
86
  G.edge_attr.update({
87
+ "color": "#616161",
88
+ "penwidth": "2.5",
89
+ "arrowsize": "1.2",
90
+ "fontname": "Arial",
91
+ "fontsize": "20",
92
+ "fontcolor": "#424242"
93
  })
94
 
95
+ # Add central node with improved styling
96
+ G.add_node("DOCUMENT",
97
+ shape="doubleoctagon",
98
+ fillcolor="#4FC3F7",
99
+ fontsize="28",
100
+ width="2.5",
101
+ height="1.0",
102
+ penwidth="3.0")
103
 
104
+ # Add entities with better spacing
105
  max_categories = 5
106
+ max_entities = 8
107
 
108
  for cat_idx, (category, values) in enumerate(entities.items()):
109
  if cat_idx >= max_categories:
110
  break
111
 
112
+ # Main category node
113
  cat_node = f"CAT_{cat_idx}"
114
+ G.add_node(cat_node,
115
+ label=wrap_label(category, 18),
116
+ shape="tab",
117
+ fillcolor="#81D4FA",
118
+ fontsize="22")
119
 
120
+ G.add_edge("DOCUMENT", cat_node,
121
+ label="contains",
122
+ penwidth="3.0")
 
123
 
124
+ # Add entities with grouping if needed
125
+ if len(values) > max_entities:
126
+ # Create subcategory groups
127
+ for sub_idx, group in enumerate([values[i:i+max_entities]
128
+ for i in range(0, len(values), max_entities)]):
129
+ sub_node = f"SUB_{cat_idx}_{sub_idx}"
130
+ G.add_node(sub_node,
131
+ label=f"Group {sub_idx+1}",
132
+ shape="folder",
133
+ fillcolor="#B3E5FC")
134
+ G.add_edge(cat_node, sub_node)
135
+
136
+ for ent_idx, value in enumerate(group):
137
+ ent_node = f"ENT_{cat_idx}_{sub_idx}_{ent_idx}"
138
+ G.add_node(ent_node,
139
+ label=wrap_label(value, 15),
140
+ shape="note",
141
+ fillcolor="#E1F5FE")
142
+ G.add_edge(sub_node, ent_node)
143
+ else:
144
+ # Directly add entities
145
+ for ent_idx, value in enumerate(values[:max_entities]):
146
+ ent_node = f"ENT_{cat_idx}_{ent_idx}"
147
+ G.add_node(ent_node,
148
+ label=wrap_label(value, 15),
149
+ shape="note",
150
+ fillcolor="#E1F5FE")
151
+ G.add_edge(cat_node, ent_node)
152
+
153
+ # Generate output with multiple attempts
154
  for engine in ['dot', 'neato', 'sfdp']:
155
  try:
156
+ G.draw(output_path,
157
+ format="png",
158
+ prog=engine,
159
+ args=f"-Gdpi=300 -Gsize=50,50 -Goverlap=prism")
160
  print(f"Successfully generated with {engine}")
161
+
162
+ # Verify the output
163
+ if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
164
+ return output_path
165
+
166
  except Exception as e:
167
  print(f"Layout engine {engine} failed: {str(e)}")
168
  continue
 
 
169
 
170
+ raise RuntimeError("All layout engines failed")
 
 
 
 
171
 
172
  except Exception as e:
173
  print(f"Mind map generation failed: {str(e)}")
174
+ # Create error visualization
175
+ try:
 
 
176
  import matplotlib.pyplot as plt
177
+ plt.figure(figsize=(20, 10))
178
+ plt.text(0.5, 0.5,
179
+ f"Mind Map Generation Failed\n{str(e)}\n\nOriginal Text:\n{text[:200]}...",
180
+ ha='center', va='center', wrap=True)
181
  plt.axis('off')
182
+ error_path = os.path.join(temp_dir, "error_mindmap.png")
183
+ plt.savefig(error_path, bbox_inches='tight', dpi=300)
184
  plt.close()
185
+ return error_path
186
+ except:
187
+ return None
188
  @app.post("/summarize")
189
  def summarize_text(request: TextRequest):
190
  chunks = [request.text[i:i+500] for i in range(0, len(request.text), 500)]
 
305
  return None
306
 
307
  mindmap_btn.click(
308
+ fn=display_mindmap,
309
+ inputs=full_doc_text,
310
+ outputs=output_mindmap,
311
+ api_name="generate_mindmap",
312
+ show_progress=True
313
  )
314
 
315
+ # Add CSS for better image display
316
+ css = """
317
+ .mindmap-container img {
318
+ max-width: 100% !important;
319
+ height: auto !important;
320
+ background: white !important;
321
+ border: 2px solid #e0e0e0 !important;
322
+ border-radius: 8px !important;
323
+ padding: 10px !important;
324
+ margin: 10px auto !important;
325
+ display: block !important;
326
+ }
327
+ """
328
+
329
  if __name__ == "__main__":
330
  iface.launch(
331
  server_name="0.0.0.0",
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10003-10041.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 104-10003-10041 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ ☐ UNCLASSIFIED
4
+ ☐ INTERNAL ONLY
5
+ ☐ CONFI**I**NTIAL
6
+ ☑ SECRET
7
+
8
+ ## ROUTING AND RECORD SHEET
9
+
10
+ SUBJECT: (Optional)
11
+
12
+ Clipping of article "The Kennedy Murder and the Secret Services of the USA"
13
+
14
+ FROM:
15
+
16
+ WE/4/INT Arthur P. Iorio
17
+
18
+ EXTENSION NO.
19
+
20
+ DATE: 26 March 1964
21
+
22
+ TO: (Officer designation, room number, and building) | DATE | OFFICER'S INITIALS | COMMENTS (Number each comment to show from whom to whom. Draw a line across column after each comment.)
23
+ -----|------|-------|-----
24
+ 1. CI Staff Birch O'Neil Room 2603 | RECEIVED | FORWARDED | The attached article, which may be of interest to you, appeared in the 7 March issue of the Italian Communist Party weekly Rinascita. The writer, Gianfranco Corsini, has been on and off US correspondent for the Italian Communist press. Note that in the section pencille in red rumors are referred which suggest that kind it was the Agency to organize the murder of President Kennedy.
25
+ 2. | | |
26
+ 3. | | |
27
+ 4. | | |
28
+ 5. | | |
29
+ 6. | | |
30
+ 7. | | |
31
+ 8. | | |
32
+ 9. | | |
33
+ 10. | | |
34
+ 11. | | |
35
+ 12. | | |
36
+ 13. | | |
37
+ 14. | | |
38
+ 15. | | 18 |
39
+
40
+ FORM 610 USE PREVIOUS EDITIONS 3-62
41
+
42
+ ☑ SECRET
43
+ ☐ CONFIDENTIAL
44
+ ☐ INTERNAL USE ONLY
45
+ ☐ UNCLASSIFIED
46
+
47
+ Clipping not retained
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143 (C06932208).md ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10004-10143
2
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+
4
+ Date: 05/08/96
5
+ Page: 1
6
+
7
+ JFK ASSASSINATION SYSTEM
8
+ IDENTIFICATION FORM
9
+
10
+ AGENCY INFORMATION
11
+
12
+ AGENCY : CIA
13
+ RECORD NUMBER : 104-10004-10143
14
+ RECORD SERIES : JFK
15
+ AGENCY FILE NUMBER : 201-289248
16
+
17
+ DOCUMENT INFORMATION
18
+
19
+ ORIGINATOR : CIA
20
+ FROM :
21
+ TO :
22
+ TITLE : DISCUSSION BETWEEN MEMBER SR DIVISION CONCERNING
23
+ OSWALD'S STAY IN HELSINKI.
24
+ DATE : 06/01/64
25
+ PAGES : 2
26
+ SUBJECTS : HELSINKI TRIP
27
+ USSR CONSULATE
28
+
29
+ DOCUMENT TYPE : PAPER, TEXTUAL DOCUMENT
30
+ CLASSIFICATION : SECRET
31
+ RESTRICTIONS : 1B
32
+ CURRENT STATUS : RELEASED WITH DELETIONS
33
+ DATE OF LAST REVIEW : 06/12/93
34
+ OPENING CRITERIA :
35
+ COMMENTS : OSW10:V43 1993.06.12.10:33:55:150000:
36
+
37
+ [R] ITEM IS RESTRICTED
38
+ NW 64937 Docld:32106269 Page 1
39
+
40
+ INTERNAL
41
+ USE ONLY
42
+ CO DENTIAL
43
+ SECRET
44
+ ROUTING AND RECORD SHEET
45
+
46
+ SUBJECT: (Optional)
47
+
48
+ FROM: CIRA/PS
49
+ 2823
50
+
51
+ TO: (Officer designation, room number, and
52
+ building)
53
+ DATE
54
+ SX-25605
55
+ 1 June 64
56
+
57
+ OFFICER'S
58
+ INITIALS
59
+ COMMENTS (Number each comment to show from whom
60
+ to whom. Draw a line across column after each comment.)
61
+ RECEIVED
62
+ FORWARDED
63
+ 1.
64
+ IPIAN
65
+ 5 MAR 1975
66
+ Phoe assign
67
+ SX # and
68
+ clamefs to
69
+ 2.
70
+ 3.
71
+ 4.
72
+ 5.
73
+ IP JEDI
74
+ 6.
75
+ 201-289248
76
+ 7.
77
+ 8.
78
+ IPIFILES
79
+ Document Number 716-838
80
+ for FOIA Review on JUN 1976
81
+
82
+ Ath Pori, Millen
83
+ 10.
84
+ 11.
85
+ 12.
86
+ 13.
87
+ 14.
88
+ 15.
89
+ FORM 610 USE PREVIOUS
90
+ NW-64937 DocId 32906269 Page 2
91
+ CONFIDENTIAL
92
+ INTERNAL
93
+ USE ONLY
94
+ UNCLASSIFIED
95
+
96
+ MEMO FOR THE RECORD
97
+ 1 June 1964.
98
+ SX-25605
99
+ Discussion betroen MOMBOR SR. Divisiong
100
+ and CoS Helsinki CONCERNING timetable
101
+ OF OSWALD'S stay in and Holsinki
102
+
103
+ 1. At 0900 this morning I talked with Frank Friberg recently
104
+ returned COS Helsinki re Warren Commission inquiry concerning
105
+ the timetable of Oswald's stay in Finland in October 1959, including
106
+ his contact with the Soviet Consulate there. (Copy of the Commission
107
+ letter of 25 May 64 and State Cable of 22 May 64 attached.)
108
+
109
+ 2. Friberg gave me the following information:
110
+
111
+ a. It takes 25 minutes to drive from the airport to
112
+ downtown Helsinki;
113
+
114
+ b. By taxi, it would take no more than 5 minutes to
115
+ reach the Soviet consulate;
116
+
117
+ C. The Soviet consulate probably closed at 1300 hours local
118
+ time on Saturdays in 1959;
119
+
120
+ d. Passenger lists (manifests) at the U.S. Consulate in
121
+ Helsinki are retained for six months only and then are destroyed.
122
+ Mr. Robert Fulton (CIA) was U.S. consular official there at
123
+ the time.
124
+
125
+ e. A copy of State's cable inquiry would go to the Helsinki
126
+ Station and they would assist in preparation of a reply.
127
+
128
+ 3. Mr. Friberg agreed that it would be worthwhile to cable che
129
+ Station concerning points not covered by State in their inquiry. He
130
+ suggested changes incorporated into the cable sent to Helsinki.
131
+
132
+ Lee H. Wigren
133
+ C/SR/CI/R
134
+
135
+ Document Number
136
+ for FOIA Review on.
137
+ 716-838
138
+ JUN 1976
139
+ SAME AS RELEASED
140
+ DOC
141
+ 340
142
+
143
+ RECORD COPY
144
+ 1
145
+ 1 Jun 64
146
+ 201-289248
147
+ NW 64937 Docld:32106269 Page 3
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10143.md ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 10.00000
2
+ 104-10004-10143 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+
4
+ 13-00000
5
+
6
+ MEMO FOR THE RECORD 1 June 1964
7
+ Sx-25605
8
+
9
+ DISCUSSION between members SR Division,
10
+ and CoS Helsinki concerning timetable
11
+ OF OSWALD'S stay in Finland and Helsinki
12
+
13
+ 1. At 0900 this morning I talked with Frank Friberg recently
14
+ returned COS Helsinki re Warren Commission inguiry concerninge.
15
+ the timetable of Oswald's stay in Finland in October 1959, including
16
+ his contact with the Soviet Consulate therer. (Copy of the Commission
17
+ letter of 25 May 64 and State Cable of 22 May, 64, attached.)
18
+
19
+ 2. Friberg gave me the following information:
20
+
21
+ a. It takes 25 minutes to drive from the airport to
22
+ Helsinki.
23
+
24
+ b. By taxi, it would take no more than 5 minutes to
25
+ reach the Soviet consulate;
26
+
27
+ c. Consulate in Helsinki was open Saturdays in 1959;
28
+
29
+ d. Passenger lists (manifests) at the Helsinki airports of
30
+ Helsinki are retained for six months only and then are destroyed.
31
+ Mr. Robert Fulton (CIA) was U.S. consular official there at
32
+ the time.
33
+
34
+ e. A copy of State's cable inquiry would go to the Helsinki
35
+ Station and they would assist in preparation of a reply.
36
+
37
+ 3. Mr. Friberg agreed that it would be worthwhile to cable the
38
+ Station concerning points not covered by State in their inquiry. He
39
+ suggested changes incorporated into the cable sent to Helsinki.
40
+
41
+ Lee H. Wigren
42
+ C/SR/CI/R
43
+ TRAVEL PROGRAM
44
+ IP/EDI ABSTRACTA
45
+ INDEX
46
+ IP/FIS
47
+ IP/PH
48
+ PREPARE FOR FICKING
49
+ FILM
50
+ CODE NO. (2,3,4)
51
+ RYBAT REST CODE
52
+ ISO/DCU
53
+ CABLE IDEN (11)
54
+ NTD (8)
55
+ IP/FILES
56
+ FOR FILING
57
+
58
+ Document Number 716-838
59
+ for FOIA Review on JUN 1976
60
+ SAME AS RELEASED
61
+ DOC -340
62
+
63
+ RECORD COPY
64
+
65
+ 1. Jun 64
66
+ 201-289248
67
+
68
+ Box 8
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10156.md ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 10.00000
2
+ 104-10004-10156
3
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
4
+
5
+ Box 8
6
+
7
+ 13-00000
8
+
9
+ 1 June 1964
10
+
11
+ MEMO FOR THE RECORD
12
+
13
+ 1. At 0900 this morning I talked with Frank Friberg recently
14
+ returned COS Helsinki re Warren Commission inquiry concerning
15
+ the timetable of Oswald's stay in Finland in October 1959, including
16
+ his contact with the Soviet Consulate there. (Copy of the Commission
17
+ letter of 25 May 64 and State Cable of 22 May 64 attached.)
18
+
19
+ 2. Friberg gave me the following information:
20
+
21
+ a. It takes 25 minutes to drive from the airport to
22
+ downtown Helsinki;
23
+
24
+ b. By taxi, it would take no more than 5 minutes to
25
+ reach the Soviet consulate;
26
+
27
+ c. The Soviet consulate probably closed at 1300 hours local
28
+ time on Saturdays in 1959;
29
+
30
+ d. Passenger lists (manifests) at the U.S. Consulate in
31
+ Helsinki are retained for six months only and then are destroyed.
32
+ Mr. Robert Fulton (CIA) was U.S. consular official there at
33
+ the time.
34
+
35
+ e. A copy of State's cable inquiry would go to the Helsinki
36
+ Station and they would assist in preparation of a reply.
37
+
38
+ 3. Mr. Friberg agreed that it would be worthwhile to cable the
39
+ Station concerning points not covered by State in their inquiry. He
40
+ suggested changes incorporated into the cable sent to Helsinki.
41
+
42
+ Document Number 780-340
43
+
44
+ FAIA Review on JUN 1976
45
+
46
+ SAME AS 716-838
47
+
48
+ ZONET
49
+
50
+ 13-00000
51
+
52
+ See Sanitized File
53
+ Number 335
54
+ For steril
55
+ H
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10004-10213.md ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10004-10213 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ YF2-27221
6
+ 9 July 1964
7
+
8
+ MEMORANDUM FOR THE RECORD
9
+ SUBJECT : Discussion with Warren Commission Staff Member
10
+ REFERENCE: Letter from J. Lee Rankin, General Counsel of the
11
+ President's Commission, to Mr. Richard Helms
12
+ dated 3 July 1964
13
+
14
+ >O SRICE DISCUSSION with SLAUSEN & Tily on .girations.
15
+ Svitt felicy towards design woats HALETICONS ANd
16
+ CUINT Visa Puccedures,
17
+ 1. With the approval of C/SR and the DDP, I met with Mr. W.
18
+ David Slawson of the staff of the President's Commission on the
19
+ Assassination of President Kennedy at 1400 hours on this date in
20
+ the Commission's offices at 200 Maryland Avenue, N.E., Washington,
21
+ D.C. The purpose of this meeting was to discuss apparent inconsistencies
22
+ in material provided the Commission by CIA and by the Department of
23
+ State which were called to our attention in a letter from the General
24
+ Counsel of the Commission to Mr. Helms, dated 3 July 1964.
25
+
26
+ 2. By way of introduction, Mr. Slawson said that in the portion of the
27
+ Commission's report that he was writing, he would have to deal with the
28
+ question of whether or not the OSWALDs' departure from the USSR - and
29
+ the circumstances (i.e. timing) of that departare were unusual or
30
+ suspicious in any way. He expressed his belief that they probably were
31
+ not and cited Soviet relaxation in such matters in the post-Stalin era.
32
+ However, he wanted to be sure in his own mind that our information was
33
+ not in conflict with that which the Commission had received from State
34
+ since all of that information would remain in the records of the
35
+ Commission.
36
+
37
+ 3. After stating my belief that there was no real disagreement or
38
+ inconsistency between the information from CLA and that from State, I
39
+ expressed the view that the matter resolved itself into three questions:
40
+
41
+ Document Number 767-864
42
+ for FOIA Review on
43
+ /a. Do the Soviet
44
+ JUN 1976
45
+
46
+ CS COPY
47
+
48
+ SECRET
49
+
50
+ a. Do the Soviet authorities normally permit Soviet
51
+ citizens married to foreign nationals to emigrate from the
52
+ Soviet Union to the homelands of their spouses?
53
+
54
+ b. Do they normally permit such Soviet citizens to
55
+ accompany (i.e. depart simultaneously with) their spouses
56
+ from the Soviet Union?
57
+
58
+ c. How long does it take such Soviet citizens to get
59
+ Soviet exit visas for such a purpose (time lapse from application
60
+ to granting of visas)?
61
+
62
+ 4. Concerning the first two questions (3a and 3b above) I pointed out.
63
+ that we had addressed ourselves mainly to the question of Sovie: citizens
64
+ being allowed to accompany their spouses abroad while State dealt only
65
+ with the larger question of Soviets married to foreigners being allowed
66
+ to emigrate without reference to whether or not they left simultaneously
67
+ with or at another time from their spouses. Mr. Slawson commented
68
+ that this explanation was most helpful and he reread what both we and
69
+ State had said in that light.
70
+
71
+ 5. By way of further explanation, I said that the statements in
72
+ paragraph 6 of our memorandum of 6 April 1964 concerning Soviets being
73
+ permitted to accompany their foreign spouses abroad were based on a
74
+ review of 26 cases, of which 10 involved Americans. In only four of
75
+ these cases did a Soviet wife leave the USSR in the company of her foreign
76
+ husband; in 14 of the cases the foreign spouse departed alone; and in the
77
+ remaining seven cases insufficient details are known to permit us to
78
+ categorize them. I added that although State's information began by
79
+ citing the issuance of 724 quota and non-quota immigrant visas by the
80
+ American Embassy in Moscow during the period FY 1954 to December
81
+ 1963, it did not indicate how many of these visas were for Soviet citizens
82
+ who had married U.S. nationals. Actually State provided detailed
83
+ information for only sixteen cases and did not indicate in many of these
84
+ whether or not the Soviet was permitted to accompany the foreign spouse.
85
+ 16. In response to
86
+
87
+ -2-
88
+
89
+ 6. In response to a question from Mr. Slawson I stated that most
90
+ of the 26 cases upon which we based our statements involved foreign
91
+ students, exchange teachers and other relatively transient persons,
92
+ and while a number of cases have certain points in common, they bear
93
+ little similarity to the OSWALD case in that none involved a defector who
94
+ married prior to repatriating. I noted that paragraph 6 of our 6 April
95
+ 1964 memorandum to the Commission had pointed this out. Mr. Slawson
96
+ indicated that he was now satisfied on this matter.
97
+
98
+ 7. Concerning the length of time taken by Soviet authorities to
99
+ process exit visas for Soviet citizens married to foreign nationals
100
+ (question 3c above), I stated that, in my opinion, the information
101
+ provided by State (in the third enclosure to Mr. Meeker's letter)
102
+ substantially corresponded to the views expressed in paragraphs 6 and 7
103
+ of our memorandum to the Commission dated 6 April 1964. Mr. Slawson
104
+ asked if it would be possible to elaborate paragraph 7 of our memorandum
105
+ of 6 April by providing a statistical breakdown of the cases on which our
106
+ statements were based. I indicated that this could be done.
107
+
108
+ 8. At this point Mr. Slawson stated that as a result of our discussion
109
+ he felt that the question of possible inconsistencies bad been resolved.
110
+ However, he asked that we send a brief written reply to the Commission's
111
+ letter of 3 July 1964 embodying the substance of what I had said concerning
112
+ the basis for statements included in our 6 April 1964 memorandum. (This
113
+ would include the gist of the draft reply to the Commission which I showed
114
+ to C/SR on 8 July plus an elaboration of our statements concerning Soviet
115
+ visa applications.]
116
+
117
+ 9. Mr. Slawson indicated that he would be sending parts of his report
118
+ dealing with the Soviet intelligence services to CIA for checking as to
119
+ their accuracy. He did not say when this would occur.
120
+
121
+ 10. After concluding the meeting with Mr. Slawson, I read Volume 52
122
+ of the transcript of testimony before the Commission. This included the
123
+ reinterview of Marina OSWALD.
124
+
125
+ -3-
126
+
127
+ Lee H. Wigren
128
+ C/SR/CI/Research
129
+
130
+ @Do. sors normally permit Sov. cityens married to for
131
+ natla to engrate pom Sll to homeland of sprise ?
132
+ • State says you - cites 724 visa applicationم
133
+ (perbably minority Spouse's; mij
134
+ belatives ite ast mijint)
135
+ - We cite absence of law; do not say.
136
+
137
+ 2 arimally
138
+ ② Do Sros permit sou. cits menit to fon marks to
139
+ accompany (ie depont simultanernely co.) spouses
140
+ from Sele to homelandes of spouses
141
+ - State does not say
142
+ se cite evidence that they do not
143
+ We ليه
144
+
145
+ ③ How long does it take Soveits to gel. Sevivians
146
+ at to homelan Ss of fou Spouses?
147
+ to junge at
148
+ -Our #7 and State's inse
149
+ فه
150
+ Cases inhuid. it ikurus ajrec
151
+
152
+ Notes, Hedin
153
+ Co
154
+ CS-COPY
155
+
156
+ dil Ite XAA2-27221
157
+
158
+ Le 7
159
+ with) friin sprστασις
160
+ Based on in de la 26 Cail
161
+ fre till out c/ SU.
162
+ (10 US)
163
+
164
+ -Safe left line oftenband - 4
165
+ -
166
+ -
167
+ -
168
+ -
169
+ - 7- !
170
+
171
+ ② Irifi in fu 47
172
+ 1-2 fine taken by for allite
173
+ bisa apple of Sor Spencer of fin
174
+ substant illy agrees is lite o infe
175
+ نر
176
+ 4. on Juice taken by Sri-st. poreias veda
177
+ aggelies of Sou woofcitis (1)
178
+
179
+ Gust of State is w
180
+ life cancion y bar, tibi of tense to her bij de citthoritie
181
+ 1.
182
+ bun cits in Sel
183
+ life in the poor
184
+ /
185
+ 740
186
+ li inquest for norme of all 1152
187
+ ت
188
+ :/ cits vitus ricerit'd in Cast
189
+ 2: 10 quo cesta Collis len, the of
190
+ fine betinien intrs of aggler. l. He apport
191
+ by God auth
192
+ 2 יני
193
+
194
+ Aun cat
195
+ 0063
196
+ >
197
+
198
+ ② Date of appplectenfor os doit reser
199
+ Ion dedures, in 14
200
+ 12
201
+
202
+ "
203
+ [10dayo-194]
204
+ Promplit all itthees
205
+ -10 line to 14 yeю
206
+ - Cant till bord
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10005-10321.md ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ CLASSIFIED MESSAGE
4
+
5
+ SECRETARTDAT
6
+
7
+ 30 September 64 FILE NO. 201-4524
8
+
9
+ BONN, FRANKFURT, BERLIN, COPENHAGEN,
10
+ REYKJAVIK, PARIS, STOCKHOLM
11
+ DIRECTOR THE HAGUE BRUSSELS
12
+
13
+ nue, stess, cluez, VR, FILE
14
+
15
+ UN, FRAN, BRLN, COPENJO GMNY
16
+ E. PARI, STOC, muda, Hagu, Beas
17
+
18
+ AT/KUDESK/TPMURILLO / CATIJA
19
+
20
+ KIGREST TRACES JOACHIM JOESTER DPOB 29 JUL 07 COLOGNE.
21
+
22
+ ENTER ENTIRE ADULT CAREER AND AUTHOR CA 30 BOOKS AND NUMEROUS
23
+ SPAPER ARTICLES. POST WWII WORKS VERY ANTI-KUBARK, LAST
24
+ OK TITLE - OSWALD: ASSASSIN OR FALL GUY? HAS WRITTEN UNDER
25
+ UE NAME AND UNDER PSEUDONYMS: FRANZ VON NESSELRODE; H.F.
26
+ LIKIN; WALTER KELL; PAUL DELATHUIS.
27
+
28
+ 2. ACCORDING CAPTURED GESTAPO DOCS HE JOINED GERM CP ON
29
+ MAY 32 AND HAD MEMBERSHIP NO. 532315. OWNED LENDING LIBRARY
30
+ LN AND SOME TIME AFTER MAY 32 WENT USSR WHERE REMAINED UNTIL
31
+
32
+ 33. DURING ABSENCE HIS LIBRARY MANAGED BY FIANCEE ANNA
33
+ SCHINSKY. LAST RESIDENCE GERMANY BRLN LUETZOWSTRASSE 40
34
+ BEI HESS.
35
+
36
+ Document Number 888-906
37
+ for FOIA Review on JUL 1976
38
+
39
+ CONTINUED
40
+
41
+ COORDINATING OFFICERS
42
+ GROUP 1
43
+ Excluded from automatic
44
+ downgrading and
45
+ declassification
46
+ AUTHENTICAT
47
+ OFFICER
48
+
49
+ SECRET/RYB
50
+ REPRODUCTION BY OTHER THAN THE ISSUING OFFICE IS PROHIBITED.
51
+
52
+ 3. IN MAY 33 FLED TO FRANCE, WAS IN COPE 36-37 BUT EXPELLED
53
+ (OR LEFT) EDCAUSE HIS ANTI-DAHISK GOVT WAITINGS. LEFT DENMARK
54
+ FOR FRANCE VIA ICELAND. IN 40 IN SWEDEN, MARRIED MAY NILSSON,
55
+ CAME US VIA USSR IN 41 AND NATURALIZED CITIZEN SINCE 48
56
+
57
+ 4. WOULD APPRECIATE AS FULL A CHECK AS POSSIBLE, INCLUDING
58
+ LOCAL SERVICES AND AVAILABLE OVERT LOCAL PRE-WWL REFERENCES
59
+ (PRESS, BOOKS, ETC.) ON JOESTEN AND FIANCEE.
60
+
61
+ 5. FOR BAIN: PLS ALSO CHECK DDC AND REQUEST PHOTOSTATS
62
+ ANY DOCS, CAN ADDRESS AND NAME HESS BE CHECKED? ANY CHANCE
63
+ LOCATE FIANCEE?
64
+
65
+ 6. ALL ADDRESSERS PLS HANDLE AEQUEST URGENTLY AS MATTER
66
+ ALSO OF INTEREST TO WARREN COMMISSION. CABLE SUMMARY RESULTS
67
+ AND POUCH DETAILS INCLUDING ALL COPIES AVAILABLE JOESTEN PRE
68
+ WWI WRITINGS.
69
+
70
+ CONTINUED
71
+
72
+ SEGRET/RVRAT
73
+
74
+ MIC PARASI THROUGK 3 AECVI IN PUBLIC DOMAIN, AUS
75
+ FILE
76
+ END OF MESSAGE
77
+
78
+ C/EE/06
79
+ C/WE/L
80
+ CAVELS
81
+
82
+ SEGRET/RVRAT
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10006-10247.md ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10006-10247
2
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+ SECRET
4
+ FROM: (Requesters name)
5
+ BRANCH
6
+ ROOM
7
+ BADGE NO.
8
+ NAME CHECK AND CONSOLIDATION REQUEST
9
+ EXTENSION
10
+ DATE
11
+ RID CONTROL NO.
12
+ TO
13
+ TUBE
14
+ ROOM
15
+ DATE
16
+ INITIALS
17
+ RID/INDEX
18
+ DT-5
19
+ REQUESTER
20
+ RID/FILES
21
+ DT-6
22
+ REQUESTER
23
+ RID/ANALYSIS GT-7
24
+ RID/201
25
+ DW-6
26
+ RID/MIS
27
+ GT-6
28
+ RID/INDEX
29
+ DT-5
30
+
31
+ SUBJECT TO BE CHECKED
32
+ SURNAME
33
+ (All spellings)
34
+ D'EDKOV, Roman Fedorovich er Vilasa Nikolaevna
35
+ SPELLING VARIATIONS TO BE CHECKED
36
+ AKA, ALIASES
37
+ OTHER IDENTIFYING DATA (Occupation, sex, CP membership,
38
+ I. S. affiliations, etc.)
39
+ Poss. at soo. Eulest. Ind
40
+ RESIDENCE
41
+ New Delhi, Ind
42
+ SEX DATE OF BIRTH
43
+ PLACE OF BIRTH
44
+ CITIZENSHIP
45
+ USSR
46
+ Minse USSR
47
+
48
+ RESULTS OF RID/INDEX CHECK
49
+ COMMENTS
50
+ NO PERTINENT IDENTIFIABLE INFORMATION
51
+ CARD REFERENCES ATTACHED
52
+
53
+ INSTRUCTIONS FOR REQUESTERS
54
+ IN ALL CASES
55
+ 1. Use gummed label; type or print all
56
+ entries.
57
+ 2. Upon receipt of index card reproductions
58
+ draw a green diagonal line across the
59
+ items you do not want.
60
+ 3. Edit (use green) the reproduced index
61
+ cards to indicate:
62
+ (a) cards to be destroyed (mark with
63
+ green D and note reason for destruction)
64
+ Examples: document destroyed; duplicate
65
+ or less informative than retained in-
66
+ formation; information of no CS value.
67
+
68
+ (b) corrections and additions, inclu-
69
+ ding infinity symbol ∞ when card in-
70
+ cludes all facts contained in the
71
+ document.
72
+
73
+ Note 1. Records of COI, SSU, OSS and CIG
74
+ are in RID/ARD, and those that meet
75
+ indexing criteria in CSHB 70-1-l are
76
+ carded in the CS Main Index. If you
77
+ believe there could be additional in-
78
+ formation of value in these records,
79
+ you must request an Archives Index
80
+ search.
81
+ 201 CONSOLIDATION
82
+ 1. Return this form with the card repro-
83
+ ductions, also return pertinent documents,
84
+ aperture cards and the dossier if a 201 on
85
+ the subject exists.
86
+ 2. For each document to be included in the
87
+ consolidation (i.e., copy or cross reference
88
+ to be placed in the 201 file), green D the
89
+ corresponding card and check (a) or (b)
90
+ below:
91
+
92
+ (a) Consolidate into
93
+ 201-
94
+ (b) Open 201 file on subject.
95
+
96
+ RESTRICTION (If any)
97
+ CRYPTONYM
98
+ OTHER INTERESTED DESKS OR STATIONS
99
+ ASSIGNED
100
+ YES
101
+ NO
102
+ FILE TO
103
+ BE KEPT
104
+ RID
105
+ DESK
106
+ Note 2. Information concerning foreign
107
+ public personalities (except mili-
108
+ tary) may be available in BR/OCR
109
+ x7997.
110
+ DATE
111
+ SIGNATURE OF RECORDS OFFICER
112
+
113
+ 13-00000
114
+
115
+ One Roman Fedorovich DEDKOV, born 28 March 1927 in Ariansk, USSR,
116
+
117
+ and his wife Vilasa Nikolayevna DEDKOV, born 31 December 1930 in Minsk,
118
+ USSR, applied for were listed as applicants for entry visas to Indiad
119
+ sometime prior to April 1962. DEDKOV, who was issued Soviet passport
120
+ number 207461 on 17 September 1960, was scheduled to arrive in New Delhi
121
+ for two years as an English language teacher at the Soviet Embassy.
122
+
123
+ It is not known whether or not DEDKOV actually arrived in New Delhi.
124
+
125
+ Not at sent because it shows lioman to Indonians, aaring
126
+ "Home List" nut classified.
127
+ SCAT
128
+ 10 AUG 1964
129
+
130
+ 13-00000
131
+
132
+ INDIA 1
133
+
134
+ DEDKOV, Roman Fedorovich
135
+
136
+ Subj scheduled to arrive New Delhi for two years as an
137
+ English teacher at the Soviet Embassy; Ppt 207461 iss
138
+ 17 Sept 60 (Mos Comment: Subj is presumed to have arr
139
+ sometime after sept 60). NBDA-8509, 24 Apr 62
140
+
141
+ Wife: Vilasa Nikolayevna (DPOB: 31 Dec 1930; Minsk)
142
+
143
+ 201-756978
144
+
145
+ DPOB: 28 Mar 1927; Ariansk
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10007-10345.md ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ ROUTING AND RECORD SHEET
4
+
5
+ SUBJECT: Document Number 988-927 BD
6
+
7
+ for FOIA Review on SEP 1976
8
+
9
+ FROM: Chief, CI/R&A
10
+ 2 C 17
11
+
12
+ TO: Chief, AF
13
+ 7 C 32
14
+
15
+ Chief, EE
16
+ 3 D 31 07
17
+
18
+ Chief, FE
19
+ 5 D 31 07
20
+
21
+ Chief, NE
22
+ 6 D 31 07
23
+
24
+ Chief, WE
25
+ 4 B 44 05
26
+
27
+ Chief, WH
28
+ 3 B 44 03
29
+
30
+ DDP
31
+ 3 C 20 16
32
+
33
+ CI/R&A
34
+ 2 C 17
35
+
36
+ PSD
37
+
38
+ RID
39
+
40
+ DATE 27-865
41
+ 24 December 1964
42
+
43
+ For Coordination
44
+
45
+ DEFERRED
46
+
47
+ RID PROUESTING STOPPED
48
+ PLEASE INDICATE HANDLING
49
+
50
+ NOTE: This Document of the CA R
51
+ of the CS Decur
52
+ Desired Handling
53
+ For Signature and Release
54
+ BY HAND
55
+ PLEASE CALL
56
+
57
+ Easy Printing 201-289248
58
+
59
+ DISPATCH
60
+
61
+ Chiefs of all Stations
62
+
63
+ Chief, KUDOVE
64
+
65
+ Warren Commission Testimony - Selected Excerpts
66
+
67
+ FYI
68
+
69
+ 1. The Warren Commission's Report on the assassination of
70
+ President Kennedy focused attention on the magnitude of the problem.
71
+ involved in the protection of the Chief Executive. As you know, it is
72
+ our responsibility, overseas and in headquarters, to render every
73
+ support possible to the Secret Service in the conduct of its statutory
74
+ responsibilities in the United States, and especially when the President
75
+ travels abroad,
76
+
77
+ 2. The circumstances confronting the Warren Commission
78
+ produced discussion and testimony on various aspects of the problem
79
+ of Presidential protection and on interagency operational cooperation,
80
+ which normally do not find their way into the public domain. These
81
+ include the acquisition and dissemination of information, consultation,
82
+ coordination, and operational interchanges. I believe you will be
83
+ interested in the attached extracts of testimony given before the Warren
84
+ Commission by U.S. intelligence and security officials. Pertinent
85
+ Fortions have been side lined. I commend these materials for reading
86
+ by all officers in positions of senior responsibility in headquarters and
87
+ overseas.
88
+
89
+ Document Number 988-927 BD.
90
+
91
+ for FOIA Review on SEP 1976
92
+
93
+ FLETCHER M. KNIGHT
94
+ 201-289245
95
+
96
+ Book Dispatch No. 4726
97
+
98
+ 100-300-12
99
+
100
+ Raymond G. Rocca gwh
101
+
102
+ HQ COPY
103
+ DISPATCH
104
+
105
+ Distribution For
106
+ Book Dispatch No. 4726
107
+
108
+ AF Division
109
+ Abidjan
110
+ Accra
111
+ Addis Ababa
112
+ Algiers
113
+ Bamako
114
+ Brazzaville
115
+ Bujumbura
116
+ Conakry
117
+ Dakar
118
+ Dar-es-Salaam
119
+ Freetown
120
+ Kampala
121
+ Khartoum
122
+ Lagos
123
+ Leopoldville
124
+ Lome
125
+ Lusaka
126
+ Mogadiscio
127
+ Monrovia
128
+ Nairobi
129
+ Pretoria
130
+ Rabat
131
+ Salisbury
132
+ Tananarive
133
+ Tripoli
134
+ Tunis
135
+ Yaounde
136
+
137
+ The above listing has been
138
+ reviewed in the AF Division.
139
+
140
+ dw
141
+
142
+ EE Division
143
+ Athens
144
+ Bern
145
+ Frankfurt
146
+ Nicosia
147
+ Vienna
148
+
149
+ The above listing has been
150
+ reviewed in the EE Division.
151
+
152
+ FE Division
153
+ Bangkok
154
+ Djakarta
155
+ Hong Kong
156
+ Honolulur
157
+ Kuala Lumpur
158
+ Manila
159
+ Melbourne
160
+ Okinawa
161
+ Phnom Penh
162
+ Rangoon
163
+ Saigon
164
+ Seoul
165
+ Taipei
166
+ Tokyo
167
+ Vientiane
168
+ Wellington
169
+
170
+ The above listing has been
171
+ reviewed in the FE Division.
172
+
173
+ себ
174
+
175
+ Distribution For
176
+ Book Dispatch No. 4726
177
+
178
+ NE Division
179
+ Aden
180
+ Amman
181
+ Ankara
182
+ Baghdad
183
+ Beirut
184
+ Cairo
185
+ Colombo
186
+ Damascus
187
+ Jidda
188
+ Kabul
189
+ Karachi
190
+ Kathmandu
191
+ Kuwait
192
+ New Delhi
193
+ Tehran
194
+
195
+ The above listing has been
196
+ reviewed in the NE Division.
197
+
198
+ WE Division
199
+ Brussels
200
+ Copenhagen
201
+ The Hague
202
+ Helsinki
203
+ Lisbon
204
+ London
205
+ Luxembourg
206
+ Madrid
207
+ Oslo
208
+ Ottawa
209
+ Paris
210
+ Paris/LCPIPIT
211
+ Reykjavik
212
+ Rome
213
+ Stockholm
214
+
215
+ The above listing has been
216
+ reviewed in the WE Division.
217
+
218
+ -2-
219
+
220
+ Distribution For
221
+ Book Dispatch No. 4726
222
+
223
+ WH Division
224
+ Asuncion
225
+ Bogota
226
+ Buenos Aires
227
+ Caracas
228
+ Georgetown
229
+ Guatemala City
230
+ Kingston
231
+ La Paz
232
+ Lima
233
+ Managua
234
+ Mexico City
235
+ Montevideo
236
+ Panama City
237
+ Paramaribo
238
+ Port-au-Prince
239
+ Port of Spain
240
+ Quito
241
+ Rio de Janeiro
242
+ San Jose
243
+ San Juan
244
+ San Salvador
245
+ Santiago
246
+ Santo Domingo
247
+ Tegucigalpa
248
+
249
+ The above listing has been
250
+ reviewed in the WH Division.
251
+
252
+ -3-
253
+
254
+ Headquarters Distribution for
255
+ Book Dispatch No. 4726
256
+
257
+ 2 DDP
258
+ 1 ADDP
259
+ 1 C/OPSER
260
+ 1 C/TSD
261
+ 1 C/CA
262
+ 1 C/CCS
263
+ 1 C/SOD
264
+ 1 C/CI
265
+ 1 C/FI
266
+
267
+ 2 C/AF
268
+ 1 C/AF/1
269
+ 1 C/AF/2
270
+ 1 C/AF/3
271
+ 1 C/AF/4
272
+ 1 C/AF/5
273
+ 1 C/AF/6
274
+
275
+ 2 C/EE
276
+ 1 C/EE/G
277
+ 1 C/EE/K
278
+ 1 C/EE/SA
279
+
280
+ 2 C/FE
281
+ 1 C/FE/CH
282
+ 1 C/FE/HULA
283
+ 1 C/FE/JKO
284
+ 1 C/FE/PMI
285
+ 1 C/FE/TBL
286
+ 1 C/FE/VNC
287
+
288
+ 2 C/NE
289
+ 1 C/NE/1
290
+ 1 DC/NE/AA
291
+ 1 C/NE/4
292
+ 1 C/NE/5
293
+ 1 C/NE/6
294
+
295
+ 2 C/WE
296
+ 1 C/WE/1
297
+ 1 C/WE/2
298
+ 1 C/WE/3
299
+ 1 C/WE/4
300
+ 1 C/WE/5
301
+ 1 C/WE/BC
302
+
303
+ 2 C/WH
304
+ 1 C/WH/1
305
+ 1 C/WH/2
306
+ 1 C/WH/3
307
+ 1 C/WH/4
308
+ 1 C/WH/5
309
+ 1 WH/COPS
310
+ 1 WH/POA
311
+ 1 WH/POB
312
+ 1 WH/Plans
313
+
314
+ 2 CI/R&A
315
+ 1 CI/LIA
316
+ 1 CI/OPS/AF
317
+ 1 CI/OPS/EE
318
+ 1 CI/OPS/FE
319
+ 1 CI/OPS/NE
320
+ 1 CI/OPS/SS
321
+ 1 CI/OPS/WE
322
+ 1 CI/OPS/WH
323
+
324
+ 1 RID
325
+
326
+ Originated by: Chief, CI/R&A, Ext. 7468/23 December 1964
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10021.md ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ FIELD DISTRIBUTION - BD #5847
6
+
7
+ AF DIVISION
8
+ Johannesburg
9
+ Lagos
10
+ Nairobi
11
+ Pretoria
12
+ Rabat
13
+ Salisbury
14
+
15
+ EUR DIVISION
16
+ Barcelona
17
+ Berlin
18
+ Bern
19
+ Bonn
20
+ Brussels
21
+ Copenhagen
22
+ Geneva
23
+ The Hague
24
+ Hamburg
25
+ Helsinki
26
+ Lisbon
27
+ London
28
+ Madrid
29
+ Milan
30
+ Munich Liaison Base
31
+ Munich Ops. Base (Laurion)
32
+ Oslo
33
+ Ottawa
34
+ Paris
35
+ LCPIPIT
36
+ Rome
37
+ Salzburg
38
+ Stockholm
39
+ Vienna
40
+ Zurich
41
+
42
+ NB DIVISION
43
+ Ankara
44
+ Athens
45
+ Beirut
46
+ Calcutta
47
+ Colombo
48
+ Istanbul
49
+ New Delhi
50
+ Rawalpindi
51
+ Teheren
52
+
53
+ FE DIVISION
54
+ Bangkok
55
+ Djakarta
56
+ Hong Kong
57
+ Honolulu
58
+ Kuala Lumpur
59
+ Kuching
60
+ Manila
61
+ Medan
62
+ Melbourne
63
+ Okinawa
64
+ Rangoon
65
+ Saigon
66
+ Seoul
67
+ Singapore
68
+ Taipei
69
+ Tokyo
70
+ Vientiane
71
+ Surabaya
72
+ Wellington
73
+
74
+ WH DIVISION
75
+ Asuncion
76
+ Bogota
77
+ Brasilia
78
+ Buenos Aires
79
+ Caracas
80
+ Georgetown
81
+ Guatemala City
82
+ Guayaquil
83
+ JMWAVE
84
+ Kingston
85
+ La Paz
86
+ Lima
87
+ Managua
88
+ Mexico City
89
+ Monterrey
90
+ Montevideo
91
+ Norfolk (REPLANT)
92
+ Panama City
93
+ Port au Prince
94
+ Porto Alegre
95
+ Quito
96
+ Recife
97
+ Rio de Janerio
98
+ San Jose
99
+ San Salvador
100
+ Santiago
101
+ Santiago de los Caballeros
102
+ Santo Domingo
103
+ Sao Paulo
104
+ Tegucigalpa
105
+
106
+ SECRET
107
+
108
+ HQS DISTRIBUTION - BD #5847
109
+
110
+ CA STAFF
111
+ DC/CA
112
+ CA/COPS
113
+ CA/PROP
114
+ CA/LO
115
+ CA/B1
116
+ CA/B2
117
+ CA/B3
118
+ CA/B4
119
+ CA/B5
120
+
121
+ AF/COPS/CA
122
+ AF/1
123
+ AF/2
124
+ AF/3
125
+ AF/4
126
+ AF/5
127
+ AF/6
128
+
129
+ FE/CA 14
130
+ C/CO/CA
131
+
132
+ SB/CA
133
+
134
+ DO/CA 3
135
+
136
+ CI/R&A 10
137
+
138
+ EUR DIVISION
139
+ E/CA
140
+ E/SC
141
+ E/BNL
142
+ E/F
143
+ E/I
144
+ E/IB
145
+ E/G
146
+ E/AS
147
+ E/BC
148
+
149
+ NE DIVISION
150
+ NE/COPS
151
+ NE/GTI/G
152
+ NE/GTI/T
153
+ NE/GTI/I
154
+ NEAA/I
155
+ NEAA/AP
156
+ NEAA/S&L
157
+ NESA/RE
158
+ NESA/C&N
159
+ NESA/I
160
+ NESA/P
161
+
162
+ WH DIVISION
163
+ WH/CA
164
+ WH/C
165
+ WH/C/CA
166
+ WH/1
167
+ WH/1/Mexico
168
+ WH/2
169
+ WH/2/G
170
+ WH/2/P
171
+ WH/H/S
172
+ WH/2/CR/N
173
+ WH/3
174
+ WH/3/B
175
+ WH/3/CO
176
+ WH/3/E
177
+ WH/3/P
178
+ WH/3/V
179
+ WH/4
180
+ WH/4/AR
181
+ WH/4/CH
182
+ WH/4/P/U
183
+ WH/5
184
+ WH/5/Brasil
185
+ WH/6
186
+ WH/7
187
+ WH/7/HT
188
+ WH/7/GU
189
+ WH/7/DR
190
+ WH/7/JTS
191
+
192
+ SECRET
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10009-10222.md ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10009-10222
2
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
3
+
4
+ SECRET
5
+
6
+ DD/P8:4635/1
7
+
8
+ 26 NOV 1968
9
+
10
+ Sir Charles C. F. Spry
11
+ Director General
12
+ Australian Security Intelligence Organization
13
+ G. P. O. Box 510583
14
+ Melbourne
15
+
16
+ Dear Charles,
17
+
18
+ Thank you for your letter of 15 October
19
+ recommending against the declassification of
20
+ Warren Commission document CD-971. I might
21
+ mention that our inquiry to you in August (1968)
22
+ was in anticipation of further pressure for the
23
+ release of Warren Commission papers, a pressure
24
+ which has not materialized. Accordingly, there is
25
+ not, at the present time, any intention to release
26
+ CD-971.
27
+
28
+ Should the question be raised at some future
29
+ time, the points made by you in your letter provide
30
+ every reason to keep the document out of the
31
+ public domain.
32
+
33
+ With kindest regards,
34
+
35
+ Sincerely,
36
+ /s/ Richard Helms
37
+
38
+ Richard Helms
39
+ Director
40
+
41
+ Document Number 1042-947c
42
+ for FOIA Review on SEP 1976
43
+
44
+ cc: DDCI
45
+
46
+ Signature Recommended:
47
+
48
+ Deputy Director for Plans
49
+ DDP/FE/PMI/AN/Amos Taylor, Jr. (X 5502):aib (25 November 1968)
50
+ 5681
51
+
52
+ Distribution:
53
+ Orig - Addee
54
+ 1 - ADDP 2 - DCI
55
+ 1 - CPE 1 - DDCI
56
+ 1 - PMI 2 - DDP
57
+ 1 - PMI/AN
58
+ 21 NOV 1968
59
+ Date
60
+
61
+ SECRET
62
+
63
+ CORRES
64
+ RELATING TO
65
+ THIS-
66
+ INCLUDING
67
+ NAVYS OK
68
+ OF 27 June
69
+
70
+ FILE
71
+ MAIN
72
+ FILE
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10022.md ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ 21 MAY
6
+ 1982
7
+ US/82/71
8
+
9
+ Dear Anthony,
10
+
11
+ Regarding your letter 6/705 of 10 May 1982, our
12
+ records indicate that Valeriy Vladimirovich Kostikov
13
+ traveled to Mexico, France, Spain, the U.S. and Cuba
14
+ during the period 1959-61. In 1961, he was assigned
15
+ permanently to Mexico City as a consular officer and
16
+ served there until August 1965. He was variously
17
+ described as a translator, vice-consul, and attache.
18
+ During this tour he attempted to cultivate a U.S.
19
+ Government employee assigned to our embassy in Mexico
20
+ City.
21
+
22
+ In September/October 1963, Lee Harvey Oswald
23
+ approached the Soviet Embassy in Mexico City in an attempt
24
+ to get a visa allowing him to return to the USSR.
25
+ Kostikov, as a consular officer, handled this visa
26
+ request. We have no information which indicates any
27
+ relationship between these individuals other than for the
28
+ purpose of Oswald's making his visa request.
29
+
30
+ Kostikov returned to Mexico City for a second tour of
31
+ duty in July 1968. During this tour he was again assigned
32
+ to the consular section and was a second secretary. It
33
+ appeared that he was tasked with following the activities
34
+ of the Central American communist parties and left-wing
35
+ groups, and he met often with members of these groups,
36
+ reportedly providing them with funds and technical
37
+ guidance. In July/August 1969, Kostikov made an unusual
38
+ TDY trip to Moscow lasting three weeks. (His family
39
+ remained in Mexico.) In July 1970 he made a four-day trip
40
+ to Havana.
41
+
42
+ Kostikov's tour in Mexico ended unexpectedly in
43
+ September 1971. Our information indicated that he was
44
+ not due to leave for another three to four months, and at
45
+ the time of his departure, there was some speculation that
46
+ the suddenness of his departure was due to the fact that
47
+ he was known to Lyalin.
48
+
49
+ CROSS FILE COPY FOR
50
+ 201-289248
51
+ DO NOT DESTROY
52
+
53
+ RECORD COPY
54
+
55
+ SECRET
56
+
57
+ XAE09222
58
+ 21MAY 82
59
+ 100-2-95
60
+
61
+ While in Mexico he was considered by some to be the
62
+ most effective and dangerous of intelligence officers in
63
+ Mexico. He has been described as being without morals,
64
+ education, and manners. Shortly after his arrival in
65
+ Mexico in 1968, he was arrested in front of a house of
66
+ prostitution after becoming involved in a fist fight with
67
+ some locals. It appears this incident did not affect his
68
+ position in Mexico City, despite the fact that it
69
+ received a good deal of press coverage.
70
+
71
+ We are aware only that Kostikov arrived in Beirut in
72
+ June 1978. We are unable to confirm his presence there
73
+ now.
74
+
75
+ Although our file indicates that Kostikov may have
76
+ been a member of Department 13 (Executive Action)
77
+ (Department V's predecessor), we have been unable to
78
+ confirm this. Also, to the best of our knowledge the KGB
79
+ has not engaged in such executive action since 1959.
80
+
81
+ Sincerely,
82
+
83
+ /s/ David
84
+
85
+ David H. Blee
86
+
87
+ Mr. Anthony C. M. DeVere
88
+
89
+ PHOTO ATTACHED
90
+
91
+ DDO/CI/RA/Joan Paxson (21 May 1982)
92
+
93
+ DISTRIBUTION:
94
+ Orig & 1 - Adse
95
+ 1 - CI/RA Chrono
96
+ 1 - 100-2-95
97
+ 1 - Reading Board
98
+ 1 - Paxson
99
+
100
+ SECRET
101
+
102
+ 100-2-95
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10024.md ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10012-10024 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ 6/705
4
+ 10 May 1982
5
+
6
+ Dear David,
7
+
8
+ VALERIY VLADIMIROVICH KOSTIKOV
9
+
10
+ 1. Please refer to our conversation of 6 May. KOSTIKOV, born 17 March 1933, Moscow, was posted to Beirut in 1978 as 1st Secretary and may still be there. He is identified KGB and served in Mexico City from 1961-71. There is a reference to him on page 307 of BARRON's KGB which suggests that he may have been Department V. We do not appear to have asked LYALIN about him, and are now doing so.
11
+
12
+ 2. We also note that EPSTEIN in "Legend" claims that according to a CIA telecheck KOSTIKOV was Lee Harvey OSWALD'S KGB case officer in Mexico City. According to BARRON (page 335) OSWALD was in Mexico between September and November 1963 and was seeking to obtain a Soviet visa. There was certainly a KGB interest in OSWALD, although according to NOSENKO this was defensive.
13
+
14
+ 3. The reason for our current interest in KOSTIKOV will be obvious. As you are aware, our Embassy in Beirut, in common with other Western Missions, has been subject to threats and violence in recent months, and in view of earlier hostile attentions from the KGB, we have been reviewing our records of KGB staff in the area who might have been involved in promoting strong-arm tactics.
15
+
16
+ 4. We would be grateful for your views as to whether the KGB are likely to be behind any of the recent incidents (possibly through the Syrians) and for any information on KOSTIKOV and his activities in Mexico and in Beirut. In particular, what are your comments on the OSWALD story; can you confirm that KOSTIKOV is still in Beirut; is there anyone else in Beirut or Damascus whose trace record suggests an Active Measures role, or worse?
17
+
18
+ 5. We should be grateful for an early reply and as I said on 6 May will treat anything you can tell us on a strictly Service to Service basis.
19
+
20
+ CROSS FILE COPY FOR
21
+ 201-289248
22
+
23
+ DO NOT DESTROY
24
+
25
+ Yours ever
26
+
27
+ A C M de Vere
28
+
29
+ Form 547a Processed
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10035.md ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ 1 UNCLASSIFIED
4
+ INTERNAL USE ONLY
5
+ CONFIDENTIAL
6
+ SECRET
7
+
8
+ ROUTING AND RECORD SHEET
9
+
10
+ SUBJECT: (Optional)
11
+
12
+ FROM: E/BC
13
+ 4C 20 Hqs?
14
+
15
+ EXTENSION NO
16
+ 1413
17
+ 7220
18
+
19
+ DATE
20
+ 5 APR 1978
21
+
22
+ TO: (Officer designation, room number, and building)
23
+
24
+ DATE
25
+ OFFICER'S INITIALS
26
+ RECEIVED
27
+ FORWARDED
28
+ COMMENTS (Number each comment to show from whom to whom. Draw a line across column, after each comment.)
29
+
30
+ 1. CilRTA
31
+ 2. Hausman APR 1978 ch
32
+ 3. Rum Holmes
33
+ 4. 3D57
34
+ 5.
35
+ 6.
36
+ 7.
37
+ 8.
38
+ 9.
39
+ 10.
40
+ This is the ACTION/INFO copy of a communication received on from MI-6 in Washington.
41
+
42
+ Another copy is being held in E/BC.
43
+
44
+ Any reply should be directed to E/BC for forwarding to Liaison.
45
+
46
+ Processing by IP is to be determined by
47
+
48
+ Coordination with E/BC is required prior to any dissemination of this information outside the DDO.
49
+
50
+ NB: Richard A. SPRAGUE, Chief Counsel and Director of HSCA, saw a copy of attached document... See his attached letter to Sergyj CZORNONOH, 04 December 1976.
51
+
52
+ RBH
53
+ 11.
54
+ 12.
55
+ 13.
56
+ 14.
57
+ 15.
58
+
59
+ FORM 610 USE PREVIOUS EDITIONS
60
+ SECRET
61
+ CONFIDENTIAL
62
+ INTERNAL USE ONLY
63
+ UNCLASSIFIED
64
+
65
+ CONFIDENTIAL
66
+
67
+ Our ref: GEN 1
68
+
69
+ Dear Art,
70
+
71
+ 30 March 1978
72
+
73
+ Please find attached correspondence received from one Sergyj CZORNONOH who claims that he provided information about Lee Harvey OSWALD to the American Vice Consul (presumably Tom Blackshear) in Sofia, Bulgaria, in August 1963.
74
+
75
+ 2. I have sent copies of these letters to the FBI and to my Head Office in London.
76
+
77
+ Mr A H Stimson
78
+
79
+ Enc.
80
+
81
+ DH Jones for GML Blackburne-Kan
82
+
83
+ CONFIDENTIAL
84
+
85
+ SERGYJ. CZORNONOH
86
+ 1106-11TH STREET
87
+ SACRAMENTO CALIFORNIA
88
+ 95814
89
+
90
+ M. Wall
91
+
92
+ TO BRITISH EMBASSY
93
+ 3100 MASSACHUSETTS AVE, N. W.
94
+ WASHINGTON, D. C.
95
+
96
+ RETURN RECEIPT REQUESTED
97
+ REGISTERED NO.257254
98
+
99
+ SERGYJ CZORNONDH
100
+ 1106-11TH STREET
101
+ SACRAMENTO, CALIFORNIA, 95814
102
+
103
+ MARCH 15, 1978.
104
+
105
+ TO BRITISH AMBASSADOR
106
+ BRITISH EMBASSY
107
+ 3100 MASSACHUSETTS AVE, N. W.
108
+ WASHINGTON, DC.
109
+
110
+ DEAR SIR.
111
+
112
+ I WROTE LETTER ON FEBRUARY 15, 1978 TO MR. JAMES CALLAGHAN PRIME MINISTER I ENCLOSED REGISTERED MAIL NO. 251067.
113
+
114
+ ON JULY 18, 1963 I WAS IN LONDON ENGLAND AT THE AIRPORT IMMIGRATION OFFICER NO. 175 I HAD NO VISA IMMIGRATION PLACE ME UNDER HOUSE ARREST, MR. SMITH IN POLICE UNIFORM SECRET SERVICE BROUGHT ME STEAK DINNER AND POLICE OFFICER INTERROGATED ME, HE ASKED ME WHAT THE EMBASSY OF US.S.R. SAY YOU HEARD IN VIENNA, AUSTRIA, I SAID I HAVE HEARD THAT ONE AMERICAN DEFECTOR (MR. LEE HARVEY OSWALD) TO RUSSIA AND HE RETURNED TO UNITED STATES OF AMERICA THIS MAN HE PREPARING TO KILL TO ASSASSINATE PRESIDENT JOHN F. KENNEDY, MR. SMITH POLICE OFFICER ASKED ME DO YOU KNOW HIS NAME, I SAID HIS NAME SOHT ONTO TIME WAS PUBLISHED ONE TIME IN NEWS PAPER IN WASHINGTON POST, MR. SMITH POLICE OFFICER SAID
115
+
116
+ I DO SEARCHING FOR THIS FILE IN BRITISH POLICE BRITISH INTELLIGENCE AND BRA IMMIGRATION, JASKING YOUR EMBASSY TO HELP TO FIND THE TRUTH AND I ASK YOUR GOVERNMENT TO FORWARD My RECORD CE JULY 181 1963 TO PRESIDENT JIMMY CARTER AND SENATOR DANIEL K. NOUYE CHAM 21. S. SENATE SELECT COMMITTEE ON IN 11 GENCE I ENCLOSE HIS Copy LETTER TO ALSO I ENCLOSE you copy LETTER I JANT ON FEBRUARY 17, 1978 TO RUSSIAN AMMASSA YOUR JUSTICE ALWAYS WILL BE APPLIA MY INCOMING MAIL iS CONTROL BY FIBI AGENTS SOME OF THE MAIL IDENT GET NOT FORWARD TO ME FIBI, Suppress My INFORMATION AND TORTURE MED DRUG RESPECTFULLY YOURS "21.S. PASSPORT NO, DO 2.7000 Sergyj
117
+
118
+ copy. 10
119
+ BRITISH AMBASSADOR
120
+
121
+ Sergyj Czornonoh
122
+ 1106- 11th Street
123
+ Sacramento, California 95814
124
+
125
+ To Russian Ambassador
126
+ Embassy of U.S.S.R.
127
+ 1125 - 16th Street
128
+ Washington, D. C.
129
+
130
+ Dear Sir:
131
+
132
+ This is retyped letter from hand written
133
+
134
+ Mr. Wasilev Consul gave me order to transmit this information to U. S. Government, on August 9, 1963 in Sofia, Bulgaria. Mr. Wasilev, Consul of Embassy of U.S.S.R., gave me this information about Mr. Lee Harvey Oswald on August 14, 1963. Mrs. Besera Asenova, girl friend of Russian Consul came to my room and repeated that Mr. Lee Harvey Oswald is assassin. He will kill President Kennedy.
135
+
136
+ On August 15, 1963 in Sofia, Bulgaria, at the airport in embassy car, I told to Mr. Blackshire, American Vice Consul, that Mr. Lee Harvey Oswald is assissin. He has a weapon or has ordered one. Mr. Blackshire said it seems like he will kill someone. I said that Mr. Lee H. Oswald is preparing to kill President of the United States, John F. Kennedy. Mr. Blackshire said where will it happen. I said they (right wing) will invite President, criticize him in the newspaper, then kill him. Mr. Blackshire told me he will give the telegram to Department of State and he gave me the address where to report.
137
+
138
+ At 9 a.m. on August 19, 1963 in Washington, D. C., I went to see (Mr. Kippingan). Director of Special Counselor Service Department of State at 1901 Pennsylvania Avenue-11th floor. I told the Director that I have information about President Kennedy. The Director said do not mention name of President Kennedy, only respond to the questions. The Director said tell us what will happen to Mr. Lee Harvey Oswald then. I said Mr. Lee H. Oswald will be killed after kill Kennedy. I said I will take the truth drug to tell the truth. Director tell us who else get killed in this country. I said as I heard, that Dr. Martin Luther King, Jr. will be killed. Who will kill Dr. King, Jr. Negro leader? I said a man who is in prison at this time. (Mr. James Earl Ray was in prison at that time.) Director asked where assassination will happen. I said in Dallas, Texas. Director said if someone gave this information here I would expel the man. Director did call on F.B.I. agents after F.B.I. use anesthesia gas to freeze me to drub me to keep amnesia.
139
+
140
+ I told Director Department of State that Mr. Lee Harvey Oswald have a weapon. Go see him. Director told me you too can have weapon--so what if Oswald got weapon.
141
+
142
+ Sincerely,
143
+
144
+ U.S House of Representatives Select Committee on Assassinations told me to write letter to Embassy in early 1977.
145
+
146
+ Sergyj Czornonoh
147
+ Regis Hotel
148
+ 1106 11th Street
149
+ Sacramento, CA 95814
150
+
151
+ GITY MANAGEAS
152
+ ABOUT HUMAN RIGHTS
153
+ BRITISH EMBASSY
154
+
155
+ February 6, 1978
156
+
157
+ Mr. John M. Price
158
+ District Attorney
159
+ Sacramento, California
160
+
161
+ Dear Mr. Price:
162
+
163
+ This is a retyped letter. I visited Mr. Ferry, Deputy District Attorney, on August 16, 1977. I told in the office that F.B.I. agents and Secret Service use police department to harass me. Police department do... supply pencil of anesthesia gas to the manager of the building I live. The manager door use certain people, to freeze me by anesthesia gas - then push drugs, poison in my mouth to torture me - to take my sleep away - or bleed by rectal and they use many other chemicals to brainwash me to use me in political assassination which I refused. On January 20, 1976 in Sacramento on 8th and I Streets, man came to me from police or post office, U.S. Department of Justice and freeze me by gas and told me to take gun, pistol and we will tell you where to go to shoot - to kill - Mr. Sargent Shriver. I refused. Manager, Mr. Sisel, of Marshall Hotel, call on the man to tell me this on the street. In February 1976, police intelligence told me that assassination will not happen here. How about to move to Maryland state.
164
+
165
+ In this letter I ask you to get report from Dr. Frederick S. Baker, M.D. colon and rectal surgery on January 31, 1978. His phone – 452-4095. I do bleed today very much and I am weak, In this letter I ask you to give re- strain order or respond to me what could be done. The right wing in America made record to use me in assassination. I refuse. I am human and I like to be treated as human. Police put frame up on me - just to take advantages on me. Police use lie, police use mental case to take advantages on me and tell me that right wing do use such people like me. To prove I enclose copy mid- night June 14, 1976. Also I enclose copy letter I sent to Mr. Ted Sheedy, Supervisor, on January 26, 1978 and copy of his reply to me.
166
+
167
+ Please respond to me. Thank you.
168
+
169
+ Very truly yours
170
+
171
+ Sergyj. Czornonoh
172
+
173
+ Mr. Sargent Shriver was run for President in 1976.
174
+
175
+ Legal Center
176
+ For The Disabled
177
+
178
+ 1722 J STREET, SUITE 19 SACRAMENTO, CA 95814
179
+ Telephone: 446-4851
180
+
181
+ March, 1978
182
+
183
+ Sergyj Czornonoh
184
+ 1106 11th Street
185
+ Sacramento, CA 95814
186
+
187
+ Dear Mr. Czornonoh:
188
+
189
+ This is to acknowledge receipt of your letter regarding difficulties you have encountered with the police and the FBI.
190
+
191
+ In the event that there is legal action taken by the police or the FBI to institutionalize you this office will provide you with legal representation.
192
+
193
+ If you have any further legal problems please contact this office.
194
+
195
+ Sincerely,
196
+
197
+ LESLIE KAY
198
+ Paralegal
199
+
200
+ CATHERINE HUGHES
201
+ Staff Attorney
202
+ LK: ab
203
+
204
+ REGISTERED NO 2.51067
205
+ FROM 1106801124 95814
206
+ TO MR. JAMES CALLAGHAN
207
+ SF Wen la OFFICE OF MINISTRY
208
+ LONDON ENGLAND
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10076.md ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 13-00000
2
+
3
+ FIELD DISTRIBUTION
4
+
5
+ A Division
6
+ WH Division
7
+ NE Division
8
+ DISTRIBUTION TO BD -
9
+ r
10
+ Abidjan
11
+ Asuncion
12
+ Amman
13
+ Accra
14
+ Fagota
15
+ Ankara 2
16
+ Addis Ababa
17
+ Erasilia
18
+ Athens 5
19
+ Апиете
20
+ Fenos Aires
21
+ Beirut 3
22
+ Bangal
23
+ Cazucas 2
24
+ Bombay
25
+ toncu
26
+ Georgetown
27
+ Calcutta
28
+ Dakar
29
+ Guatemala
30
+ Colombo
31
+ Ier at Salava
32
+ Quayaquil
33
+ Dacca
34
+ Kaipals
35
+ Kingstoc
36
+ Istanbul
37
+ Freetown
38
+ La Paz
39
+ Jerusalem
40
+ Khartoum
41
+ Lima
42
+ Jidda
43
+ Kiastasa
44
+ Keduaa
45
+ Mexico City 2
46
+ Kabul
47
+ Mutevideo
48
+ Karachi
49
+ Lagos
50
+ Рапяка
51
+ Katmandu
52
+ Lusaka
53
+ Forte Alegre
54
+ Kirwait
55
+ Mogadiscio
56
+ Av Spain
57
+ Lahore
58
+ Moarovia
59
+ Madras
60
+ CI/ICG
61
+ Nairobi
62
+ Recife
63
+ New Delhi
64
+ Rabat
65
+ Rio de Janeiro 2
66
+ Nicosia
67
+ Tripoli
68
+ San Jose
69
+ Rawalpindi
70
+ Yamade
71
+ Sau Salvador
72
+ Teheran
73
+ Santiago 2
74
+
75
+ Sento Domiαει
76
+ EUR Division
77
+ Ses Paulc
78
+ Berlin 3
79
+ Tegucigalpa
80
+ Bern
81
+ Madrid 2
82
+ Bona 5
83
+ Preseis
84
+ Copenhagen
85
+ Frankfurt
86
+ FE Divisi
87
+
88
+ Do agirak 3
89
+ karta
90
+ 3
91
+ AF/2
92
+ Heleinkta
93
+ 2
94
+ 4
95
+ karta 2
96
+ Matid
97
+ 2
98
+ TALA Lumpur
99
+ Munich betria) 3
100
+ Mars la
101
+ 2
102
+ Me ibaurtu
103
+ Peru
104
+ kizawa
105
+ Pame
106
+ 2
107
+ כם
108
+ stockholm
109
+ Sat 2
110
+ Sen
111
+ ogue 2
112
+ Singapora
113
+ Vine
114
+ Suracaye
115
+ Zurich
116
+ Taipei 2
117
+ Tokyo
118
+ 2
119
+ Vientians
120
+ Wellington
121
+ BD 6614?
122
+ SB/Division
123
+ C/SB
124
+ SB/CA
125
+ SB/BR
126
+ SB/C
127
+ SB/YA
128
+ SB/P
129
+ SB/CI
130
+
131
+ WH/C/CA/PROP 2
132
+ WH/CA
133
+
134
+ WH/1,2,3,4,5
135
+ WH/7/JTS, CU
136
+
137
+ 1-D/RR
138
+ 2-DOCA
139
+ CI/FA
140
+
141
+ FBID/Weisa
142
+ VTR/SIC
143
+ OTR/Isolation Library
144
+ FL/8PG
145
+ MPS/PSC
146
+
147
+ CS Special Group Offic
148
+ INTERNAL DISTRIBUTION
149
+ AP/COP/CA
150
+ AP/1
151
+ C/CA - DC/CA
152
+ C/CA/PEG
153
+ AP/L
154
+ CA/EL 3
155
+ AF/5
156
+ 08/53 3
157
+ CA/DA
158
+ AF/6-Ethiopia
159
+ 40/80
160
+ C/EUR
161
+ E/ONE/CA
162
+ CA/FROF
163
+ E/G
164
+ 8/A8
165
+ B/SC
166
+ E/BNE
167
+ E/BC
168
+ E/F
169
+ ق
170
+ 1/2
171
+ E/LB
172
+
173
+ FE/CA 16
174
+
175
+
176
+ NE/SA/A
177
+ NE/GTA!!
178
+ NE/GES T
179
+ NF 'COPS
180
+ NEGA/I
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10078.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+ 104-10012-10078
3
+ QUNCLASSIFIED
4
+ ONLY
5
+ ROUTING AND RECORD SHEET
6
+ ENTIAL
7
+ SECRET
8
+ SUBJECT: (Optional)
9
+ FROM:
10
+ Chief Far East Division
11
+ TO: (Officerdesignation, room number, and.
12
+ building)
13
+ EXTENSION NO.
14
+ FORWARDED
15
+ OFFICER'S
16
+ INITIALS:
17
+ DATE
18
+ 20 Nov.68
19
+ COMMENTS (Number each comment to show from whom
20
+ to whom. Draw a line across column after each comment.)
21
+ DATE
22
+ RECEIVED
23
+ Chief CI Staff 27 NOV 1968
24
+ CIRA
25
+ Mr. Dooley
26
+ 27 NOV 1968
27
+ boo
28
+ for file
29
+ Document Number
30
+ येद
31
+ 1128-988
32
+ for FOIA Review on SEP 1976
33
+ 201-289248
34
+ FORM
35
+ 3-62
36
+ 610
37
+ USE PREVIOUS
38
+ EDITIONS
39
+ SECRET
40
+ CONFIDENTIAL
41
+ INTERNAL
42
+ USE ONLY
43
+ UNCLASSIFIED
44
+
45
+ UNCLASSIFIEDERAL CO DENTIAL
46
+ SUBJECT: (Optional)
47
+ FROM: CIRAIRS
48
+ 2323
49
+ TO: (Officer designation, room number, and
50
+ building)
51
+ 1.
52
+ IP/AN
53
+ 2.
54
+ 3.
55
+ 4.
56
+ 5.
57
+ JP/EDI
58
+ 6.
59
+ 7.
60
+ 8.
61
+ 9.
62
+ 10.
63
+ Document Number
64
+ for FOIA Review on
65
+ 28/Flas
66
+ HP/RMS
67
+ 12.
68
+ 13.
69
+ ONLY
70
+ ROUTING AND RECORD SHEET
71
+ EXTENSION NO.
72
+ DATE
73
+ OFFICER'S
74
+ INITIALS
75
+ RECEIVED
76
+ FORWARDED
77
+ DATE
78
+ 26 που. 68
79
+ XAAZ-35926
80
+ 26 NOU 68-
81
+ SECRET
82
+ COMMENTS (Number each comment to show from whom
83
+ to whom. Draw a line across column after each comment.)
84
+ @ Please asijo
85
+ XAAZ # and
86
+ os pay & Of
87
+ 1128-988
88
+ SEP 1976
89
+ MAY
90
+ 1978
91
+ clamifs to
92
+ 201-289748
93
+ 26.
94
+ Date: 2 NOV 68)
95
+ Salgent
96
+ Covesperelerce Cotisan
97
+ 0%
98
+ CIA and ASIO.
99
+ Re: release
100
+ of exftinatun ly
101
+ Woven Commessen
102
+ 14.
103
+ 15.
104
+ FORM
105
+ 3-62
106
+ D
107
+ 610
108
+ USE PREVIOUS
109
+ EDITIONS
110
+ SECRET
111
+ CONFIDENTIAL
112
+ INTERNAL
113
+ USE ONLY
114
+ UNCLASSIFIED
115
+
116
+ SECRET
117
+ 20 NOV 1968
118
+ KEMORANDUM FOR: Director of Central Intelligence
119
+ VIA
120
+ SUBJECT
121
+ Deputy Director for Plane
122
+ 304635
123
+ Executive Registry
124
+ 68-516011
125
+ XAAZ-
126
+ 35926
127
+ Letter for Direstor from Bir Charles Spry (ASIO)
128
+ 1. Attached is a scaled letter fron Sir Charles Spry,
129
+ Director General of the Australian Security Intelligenco
130
+ Organization (who provided a copy of the letter to the Chief
131
+ of Station, Heibourne), and a suggested reply for your
132
+ signature.
133
+ 2. Bir Charles' letter to you recommends again好家
134
+ doclassification of the Farrea Comaission document CD-971,
135
+ which refers to our investigation of anonymous telephone
136
+ calls to the Canberra Babassy before and after the
137
+ amcassination of President Kennedy.
138
+ 3. I consider the points made by Bir Charles in his
139
+ letter to be valid and accordingly recommend against the
140
+ decisosification of CD-971 in the foreseeable fature
141
+ Staff concurs with this recommendation.
142
+ Document Number 1128-988
143
+ for FOLA Review on SEP 1976
144
+ 4. Naison
145
+ William E. Nelson
146
+ of
147
+ K
148
+ P/ERI
149
+ Chief, Far East Division
150
+ Attachments, 5
151
+ 130/900
152
+ A.
153
+ Letter from Sir Charles Spry
154
+ PROCARE FOR THAUNG
155
+ 575 40. (2.3.4)
156
+ AVGAT REST, CODE
157
+ CABLE ICON (11)
158
+ (4)
159
+ B.
160
+ Letter Replying to Sir Charles Spry
161
+ P/FRES
162
+ FOR FILING
163
+ C. FAMA 5008, subject: Declassification of Warreh
164
+ Commission Document CD-971-
165
+ D.
166
+ Copy of CD-971
167
+ E. FAMW 3636, subject: Request for Release of Warren
168
+ Commission Document
169
+ 20: DOCI
170
+ DDP/FE/PMI/AN: Amos Taylor, Jrl:arc (19) November 1968)
171
+ Distribution
172
+ Orig & 1
173
+ -
174
+ Addressee
175
+ 1 DDCI
176
+ -
177
+ 2
178
+ -
179
+ 1
180
+ DDP
181
+ ADDP
182
+ RECORD COPY
183
+ -
184
+ 1
185
+ 1
186
+ 1
187
+ -
188
+ 1
189
+ -
190
+ GEODET
191
+ C/CI Staff
192
+ CFE
193
+ CFE/PMI
194
+ wanatic
195
+ ...and
196
+ neslassification
197
+ CFE/PMI/AN
198
+ 26 που 68
199
+ 201-289248
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10012-10079.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+
5
+ 68-2/60/a
6
+ RD/08-4635/
7
+
8
+ 26 NOV 1968
9
+
10
+ FILE
11
+
12
+ Sir Charles C. F. Spry
13
+ Director General
14
+ Australian Security Intelligence Organization
15
+ G. P. O. Box 51058B
16
+ Melbourne
17
+
18
+ Dear Charles,
19
+
20
+ Thank you for your letter of 15 October
21
+ recommending against the declassification of
22
+ Warren Commission document CD-071. I might
23
+ mention that our inquiry to you in August (1968)
24
+ was in anticipation of further pressure for the
25
+ release of Warren Commission papers, a pressure
26
+ which has not materialized. Accordingly, there is
27
+ not, at the present time, any intention to release
28
+ CD-971.
29
+
30
+ Should the question be raised at some future
31
+ time, the points made by you in your letter provide
32
+ every reason to keep the document out of the
33
+ public domain.
34
+
35
+ With kindest regards,
36
+
37
+ Sincerely,
38
+
39
+ /s/ Richard Helms
40
+
41
+ Richard Helms
42
+ Director
43
+
44
+ cc: DDCI
45
+
46
+ Signature Recommended:
47
+
48
+ Deputy Director for Plans
49
+
50
+ Distribution:
51
+ Orig - Addee
52
+ 1 - ADDP 2 - DCI
53
+ 1 - CFE 1 - DDCI
54
+ 1 - PMI 2 - DDP
55
+ 1 - PMI/AN
56
+
57
+ Date
58
+
59
+ DDP/FE/PMI/AN/Amos Taylor, Jr. (X 5502):aib (25 November 1968)
60
+
61
+ 201-289248
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10014-10051.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
2
+
3
+ SECRET
4
+ IMS(FABOSS)
5
+
6
+ SECRET
7
+ FRP: ,2,
8
+
9
+ STAFF
10
+
11
+ ACTION: C/EUR/NOR (729) INFO: EUDORECORD, EUR/LGL, MDSX, ODPD RYBAT.(FILE,
12
+
13
+ OC/EURN, CIC/EUR (3/W)
14
+
15
+ 96 3123036 ASO PAGE 001 IN 3123036
16
+ TOR: 081248Z FEB 96 (COPB 94608
17
+ SECRET 081247Z FEB 96 STAFF 19-6
18
+ CITE:(COPENHAGEN)94608
19
+
20
+ TO: IMMEDIATE DIRECTOR.
21
+
22
+ FOR: LIMIT EUR/(NOR) INFO DC/EURN) CIC (EU, EUR/LGL)
23
+
24
+ SLUGS: WNINTEL RYBAT
25
+
26
+ SUBJECT: RELEASE OF CLASSIFIED DOCUMENT
27
+
28
+ REF: DIRECTOR 633349 96 3117723
29
+
30
+ TEXT:
31
+
32
+ 1. ACTION REQUIRED: SEE PARA 2.
33
+
34
+ 2. THE FAX (STATION) RECEIVED APPEARS TO BE INCOMPLETE. IT
35
+ CONTAINED A COVER SHEET, A ONE-PAGE COPENHAGEN) CABLE STATING "NO
36
+ TRACES" AND THE FIRST PAGE OF A DIRECTOR CABLE REQUESTING TRACES ON
37
+ LEE HARVEY ((OSWALD)). UNLESS THE MISSING PORTIONS OF THE DIRECTOR
38
+ CABLE HAVE SOME BEARING ON (DENMARK, STATION) CANNOT MAKE A CASE
39
+ AGAINST RELEASE OF THIS MATERIAL WE WOULD INSIST, HOWEVER, THAT
40
+ CRYPTS BE DELETED - AS REF INDICATED WOULD BE THE CASE.
41
+
42
+ 3. PLEASE KEEP US APPRISED OF DATE THESE DOCS WILL BE RELEASED
43
+ SO THAT (STATION) MAY INFORM AMBASSADOR AND OUR LIAISON SERVICE
44
+ CHIEFS.
45
+
46
+ 4. CL BY: 0716497 CL REASON: 1.5(C) DECL ON: X1
47
+
48
+ 4....FILE: 021-120-004/1. DECL DRV. HUM 4-82.
49
+
50
+ END OF MESSAGE SECRET
51
+
52
+ SECRET
53
+
54
+ DO NOT DESTROY
55
+ CROSS FILE COPY FOR:
56
+ 201-0289248
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10014-10064.md ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SECRET
2
+
3
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
4
+
5
+ OPERATOR: SEEGER, EDWA BADGE: KT283 DATE : 14 SEP 93
6
+ OFFICE : IMS/FABOSS PHONE: 047552 TIME : 15:24
7
+ ROOM : GC520HB PRINTER: T019 PAGE : 001
8
+ REQUESTER: HM877
9
+ DSN: SPET 21162 DOC DATE: 20 NOV 91 MHF#: 91-6320813
10
+
11
+ //
12
+
13
+ SECRET FRP:
14
+ STAFF
15
+
16
+ ACTION: SE/USSR/10-3 (752) INFO: C/ORMS, DOMDS, LIMITO, ODPD, SEDORECORD.
17
+ FILE, DDO-2, SE/RR-3 (9/W)
18
+
19
+ 91 6320813 ASR PAGE 001 IN 6320813
20
+ TOR: 201455Z NOV 91 SPET 21162
21
+
22
+ SECRET 201454Z NOV 91 STAFF
23
+
24
+ CITE ST PETERSBURG 21162
25
+
26
+ TO: MOSCOW INFO DIRECTOR.
27
+
28
+ FOR: LIMIT SE/USSR/10 INFO SE/RR
29
+
30
+ SLUGS: WNINTEL GTDANCER
31
+
32
+ SUBJECT: KGB OFFICIAL NIKONOV
33
+
34
+ REF: NONE
35
+
36
+ TEXT:
37
+
38
+ 1. ACTION REQUIRED: NONE.
39
+
40
+ 2. DURING THE WEEK OF 3-9 NOVEMBER 1991, U.S. PROFESSOR
41
+ Ε.Β. ((SMITH)), HAD SEVERAL DISCUSSIONS IN MOSCOW WITH "SLAVA"
42
+ ((NIKONOV)), WHO IS A LONGTIME FRI?ND AND NOW DEPUTY TO KGB
43
+ DIRECTOR ((BAKATIN)). THE PROFESSOR HAS KNOWN NIKONOV WELL
44
+ SINCE 1976. HE CURRENTLY IS INSTRUCTING ON A FULBRIGHT GRANT
45
+ AT ST PETERSBURG STATE UNIVERSITY UNTIL 22 DECEMBER 1991. SEE
46
+ PARA 7 FOR BIO ON THE PROFESSOR. DCOB STEVEN R. HEIBERG HAS
47
+ BEFRIENDED THE PROFESSOR, WHO WAS DINNER GUEST AT HEIBERG'S
48
+ HOME ON 10 NOVEMBER AND PROVIDED THE FOLLOWING INFO ON NIKONOV
49
+ AND HIS NEW KGB JOB.
50
+
51
+ 3. NIKONOV IS THE GRANDSON OF FORMER SOVIET FOREIGN
52
+ MINISTER VYACHESLAV MOLOTOV. THE U.S. PROFESSOR TAUGHT NIKONOV
53
+ IN 1976 AT MOSCOW STATE UNIVERSITY WHILE A FULBRIGHT
54
+ PROFESSOR. NIKONOV WAS REGARDED AS EXTREMELY INTELLIGENT AND
55
+ CAPABLE BUT GAVE THE IMPRESSION THAT HE WAS AN IDEOLOGICAL
56
+ HARDLINER. THE PROFESSOR BELIEVED THAT HE WAS LIKELY TO BE A
57
+ RISING STAR IN THE SOVIET SYSTEM AND RECOMMENDED HIM FOR AN
58
+ IREX-SPONSORED VISIT TO THE U.S. AS EXPECTED, NIKONOV'S VIEWS
59
+ AND RHETORIC MODERATED VERY VISIBLY AFTER HIS FIRST DIRECT
60
+ EXPOSURE TO THE U.S. HE HAS HAD AT LEAST ONE ADDITIONAL
61
+ IREX-SPONSORED TRIP TO THE U.S. AND HAS SPENT PERIODS OF TIME
62
+ AS A PERSONAL GUEST AT THE HOME OF THE U.S. PROFESSOR IN
63
+ MARYLAND.
64
+
65
+ 4. ΝΙΚΟΝNOV CAME TO WORK IN HIS POSITION AT THE KGB AS A
66
+ RESULT OF BEING A CLOSE FRIEND OF BAKATIN. DURING THE AUGUST
67
+ 1991 COUP ATTEMPT NIKONOV SAID THAT HE REFUSED TO FOLLOW HIS
68
+ BOSS'S ORDER TO ACT IN ACCORDANCE WITH THE DECLARED STATE OF
69
+ EMERGENCY. HE WAS DISMISSED BY HIS BOSS (NFI) FROM THIS
70
+ POSITION AND CALLED BAKATIN TO SEEK ADVICE. BAKATIN SAID HE
71
+ WAS ALSO OPPOSING THE COUP AND WOULD LOOK OUT FOR NIKONOV ONCE
72
+ ORDER WAS RESTORED. SOON AFTER THE COUP BAKATIN CALLED HIM TO
73
+ ASK THAT HE ASSIST WITH RESTRUCTURING THE KGB. AFTER IT WAS
74
+ AGREED THAT NIKONOV COULD DECLINE TO ACCEPT TWO-STAR MILITARY
75
+ KGB RANK AND WORK IN THE JOB FOR AN EQUIVALENT CIVILIAN
76
+ COMPENSATION PACKAGE, HE CAME TO THE KGB AS BAKATIN'S DEPUTY.
77
+ NIKONOV SAID HIS FRIENDS WERE DELIGHTED THAT HE HAD DECLINED
78
+ THE KGB COMMISSION.
79
+
80
+ 5. ΝΙΚΟΝOV'S FIRST ASSIGNMENT FROM BAKATIN WAS MAKING
81
+ ARRANGEMENTS FOR THE KGB-CIA LIAISON RELATIONSHIP WHICH HAS NOW
82
+ COME INTO BEING. IN PREPARATION FOR ONE POSSIBLE QUESTION
83
+
84
+ <<< TEMPORARY WORKING COPY DESTROY AFTER USE >>>
85
+ SECRET
86
+
87
+ # SECRET
88
+
89
+ OPERATOR: SEEGER, EDWA BADGE: KT283 DATE : 14 SEP 93
90
+ OFFICE : IMS/FABOSS PHONE: 047552 TIME : 15:24
91
+ ROOM : GC520HB PRINTER: T019 PAGE : 002
92
+ REQUESTER: HM877
93
+ DSN: SPET 21162 DOC DATE: 20 NOV 91 MHF#: 31-63208:3
94
+
95
+ WHICH MIGHT BE RAISED, NIKONOV PERSONALLY REVIEWED KGB FILES TO
96
+ DETERMINE IF LEE HARVEY ((OSWALD)) HAD BEEN A KGB AGENT. HE
97
+ REVIEWED FIVE THICK VOLUMES OF FILES ON OSWALD. NIKONOV IS NOW
98
+ CONFIDENT THAT OSWALD WAS AT NO TIME AN AGENT CONTROLLED BY THE
99
+ KGB. FROM THE DESCRIPTION OF OSWALD IN THE FILES HE DOUBTED
100
+ THAT ANYONE COULD CONTROL OSWALD, BUT NOTED THAT THE KBG
101
+ WATCHED HIM CLOSELY AND CONSTANTLY WHILE HE WAS IN THE USSR.
102
+ HE COMMENTED THAT OSWALD HAD A STORMY RELATIONSHIP WITH HIS
103
+ SOVIET WIFE, WHO RODE HIM INCESSANTLY. THE FILE ALSO REFLECTED
104
+ THAT OSWALD WAS A POOR SHOT WHEN HE TRIED TARGET FIRING IN THE
105
+ USSR.
106
+
107
+ 6. IN PREPARATION FOR ESTABLISHMENT OF A LIAISON
108
+ RELATIONSHIP WITH THE SWEDISH INTELLIGENCE SERVICE, NIKONOV
109
+ PERSONALLY PERFORMED AN INQUIRY FOR BAKATIN INTO THE FATE OF
110
+ SWEDISH DIPLOMAT RAOUL ((WALLENBERG)). THERE IS STILL PRESSURE
111
+ FROM THE SWEDISH SIDE TO HAVE A DEFINITIVE ANSWER ON THIS
112
+ MATTER BECAUSE OF THE CONTINUING IMPORTANCE OF THE WALLENBERG
113
+ FAMILY. NIKONOV WAS AMAZED TO FIND OUT THAT THE KG3 HAD NOT
114
+ BEEN ABLE TO PREVIOUSLY ESTABLISH WHETHER WALLENBERG HAD DIED
115
+ AND UNDER WHAT CIRCUMSTANCES. HE WAS ABLE TO FIND PARTIAL
116
+ EVIDENCE FROM FOURTEEN DIFFERENT SOURCES (NF:). NIKONOV NOW
117
+ BELIEVES, BUT FOUND NO CONCLUSIVE PROOF, THAT WALLENBERG WAS
118
+ EXECUTED LATE IN 1947. THERE WERE INDICATIONS THAT WALLENBERG
119
+ WAS SUSPECTED OF HAVING CONTACTS WITH OTHERS WHO WERE ACCUSED
120
+ OF PROVIDING FALSE DIPLOMATIC IDENTITY DOCUMENTS TO OTHERS
121
+ BEYOND JEWS SAVED FROM THE HOLOCAUST. AMONG THESE WERE NAZI
122
+ WAR CRIMINALS WHO WERE ALLOWED TO ESCAPE. THERE WAS NO PROOF
123
+ OF WALLENBERG'S GUILT IN ANY OF THESE CHARGES.
124
+
125
+ 7. FULBRIGHT PROFESSOR WHO IS NIKONOV'S FORMER PROFESSOR
126
+ AND FRIEND IS:
127
+ NAME: Ε.Β. ((SMITH))
128
+ DOB: C.1920
129
+ CIT: USA
130
+ OCC: PROFESSOR OF HISTORY AT UNIVERSITY OF MARYLAND,
131
+ RETIRED
132
+ LOC: RESIDES NEAR ANNAPOLIS, MD
133
+ OTHER: FULBRIGHT PROFESSOR FOR WINTER 1991 TERM IN ST
134
+ PETERSBURG STATE UNIVERSITY, USSR, TWO PREVIOUS FULBRIGHT
135
+ ASSIGNMENTS IN MOSCOW AND SEVERAL IN PRC AND GERMANY; HOSTS
136
+ FORMER STUDENTS FROM USSR AND PRC ON U.S. VISITS
137
+ THERE ARE NO BASE TRACES ON SMITH. HE SERVED IN THE
138
+ MILITARY AND IS VERY WELL DISPOSED TOWARDS THE U.S.
139
+ GOVERNMENT. HE VOLUNTEERED INFO ON NIKONOV AND OTHER USSR, PRC
140
+ AND GERMAN CONTACTS TO HEIBERG AND CAN PROVIDE CONSIDERABLE 810
141
+ AND ASSESSMENT INFO ON THEM.
142
+
143
+ 8. FILE: 074-005-011, 201-0005925
144
+ DEFER. DECL OADR DRV HUM 4-82.
145
+ END OF MESSAGE SECRET
146
+
147
+ END OF DOCUMENT
148
+
149
+ <<< TEMPORARY WORKING COPY DESTROY AFTER USE >>>
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10016-10021.md ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 104-10016-10021
2
+
3
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
4
+
5
+ CLASSIFIED MESSAGE
6
+
7
+ SECRET
8
+
9
+ ROUTING
10
+ 1
11
+ 2
12
+ 4
13
+ 5
14
+ 6
15
+
16
+ DIRECTOR
17
+ RECORDS OFFICER STAMP
18
+
19
+ MELBOURNE
20
+ The following action is authorized: DE SENSITIZE
21
+
22
+ CAMH
23
+ Signed: R. Haufton
24
+ DCI, D/DCI, DDP, C/CI, C/CI/SI, VR
25
+ R.O. #1 - Unit: CI/RKA
26
+ CS COPY
27
+
28
+ SECRET 0204222
29
+ Note: If destruction, cite reasons and coordinate if appropriate.
30
+
31
+ DIR INFO CNBR CITE MELB 2517 (ROLLOFIER ACTING)
32
+ 2 DEC 63 IN 71187
33
+ AVDAT GPFLOOR
34
+
35
+ REF DIR 85690
36
+
37
+ 1. SQUARE PRELIMINARY CHECKS ON RECORDED CONVERSATIONS REVEAL FOLL:
38
+
39
+ A NO TRACE 1952 DARK BLUE BUICK BELONGING SOVIET OR BLOC INSTALLATION CNBR OR SYDNEY.
40
+
41
+ B NO LICENSE PLATE IDENTICAL TO ONE MENTIONED BUT FOLL N.S.W. VARIANTS CHECKED: CCC 012, 1960 VAUXHALL, TWO-TONED BLUE, HERMAN SATRAPINSKY, 149 WENTWORTH AVE, WENTWORTHVILLE; CCC 122, 1949 STANDARD, FAUN, WILLIAM JOHN SIMS, BINALONG; CCO 122, 1960 HOLDEN, BIEGE, KEITH BETHKE, 28 HEWITT AVE, WAHROONGA. NO SQUARE DEROG ON ABOVE.
42
+
43
+ Document Number 270-676 for FOIA Review on. MAY 1976
44
+ C NO IDENTIFIABLE INFO ON AUSSIE MENTIONED CNBR 9591.(IN 68838)
45
+
46
+ D FRASERS MENTIONED SAME REF ARE ALP MPS.
47
+
48
+ E INDON FIRST SECY POSSIBLY IDW R. WILLY SASTRANEGARA HAS MOUSTACHE; RUSSIAN CAPABILITY NOT KNOWN TO SQUARE; NOT NOTICEABLY CLOSE TO SOVS CNBR.
49
+
50
+ D: 200-5-41
51
+ CLASSIFICATION REVIEW
52
+ CS COPY CONDUCTED ON 24 MAY 1970 1289248
53
+ E IMPDET CL BY 012208
54
+
55
+ GROUP
56
+ SECRET
57
+ Excluded from ovlomatic downgrading and declassification
58
+
59
+ REPRODUCTION BY OTHER THAN THE ISSUING OFFICE IS PROHIBITED
60
+ Copy No.
61
+
62
+ 13-00000
63
+
64
+ CLASSIFIED MESSAGE 71187 PAGE 2
65
+
66
+ 2. SQUARE HAS ARRANGED WITH PMG LIAISON OFFICER TED YOUNG TRACE ANY FURTHER CALLS MADE. EMBASSY IN CLOSE CONTACT SQUARE REP CNBR.
67
+
68
+ 3. WILL ADVISE FURTHER DEVELOPMENTS.
69
+
70
+ SECRET
71
+
72
+ C/S COMMENY: Hqs requested information on the Polish driver connected with the Russian diplomatic establishment in Australia.
73
+
74
+ SECRET
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/jfk_text/104-10023-10087.md ADDED
@@ -0,0 +1,907 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 1400000
2
+ 104-10023-10087
3
+ 2025 RELEASE UNDER THE PRESIDENT JOHN F. KENNEDY ASSASSINATION RECORDS ACT OF 1992
4
+
5
+ ( SECRET DO NOT REPRODUCE
6
+ RETURN TO CIA
7
+ (
8
+ DOHB 70-1-1
9
+ CHAPTER III
10
+ 15 November 1974
11
+ ANNEX B
12
+ THE 201 SYSTEM
13
+ RETURN TO CIA
14
+ Background Use Only
15
+ Do Not Reproduce
16
+ :
17
+
18
+ Rescission: Annex B of Chapter III, CSHB 70-1-1, 27 October 1966
19
+
20
+ 1. INTRODUCTION
21
+
22
+ The 201 system provides a method for identifying a person of specific in-
23
+ terest to the Operations Directorate and for controlling and filing all pertinent
24
+ information about that person. The system also provides a means for identifying
25
+ subjects of 201 files from various categories of information about them and for
26
+ producing lisits of 201 personalities according to those categories. Only a rela-
27
+ tively small number of personalities indexed are of sufficient interest to justify
28
+ opening a 201 dossier. These are normally subjects of extensive reporting and
29
+ CI investigation, prospective agents and sources, members of groups and organi-
30
+ zations of continuing target interest, or subjects on whom a volume of corre-
31
+ spondence has accumulated.
32
+
33
+ 2. THE 201 SYSTEM
34
+
35
+ The principal features of the 201 system are:
36
+
37
+ a. The 201 Number: a unique number, i.e., 201-1234567, assigned to each
38
+ individual in the system to serve as identifying file number for reporting on that
39
+ individual.
40
+
41
+ b. The 201 Dossier: the official file containing the 201 opening form (Form
42
+ 831) and all biographic reporting on and references to the individual, i.e., per-
43
+ sonal history, current status, and prospects.
44
+
45
+ c. The Master 201 Record: a machine record generated by the opening of
46
+ a 201 file. This record produces the master 201 reference for the Main Index and
47
+ stores the pertinent information which may later be retrieved for special listings.
48
+
49
+ d. Main Index Master 201 Reference: this reference, printed in reply to an
50
+ Index Search Request, is printed as illustrated below. When data are absent
51
+ within the record, succeeding data items or lines will be moved up and the ref-
52
+ erence consolidated..
53
+
54
+ SECRET
55
+ 14-00000
56
+ SECRET
57
+ (
58
+ DOHB 70-1-1
59
+ CHAPTER III, ANNEX B
60
+ 15 November 1974
61
+
62
+ 0002 CROIX, WILLIAM PENDLETON
63
+ SEX M DOB 12 APR 26
64
+ CIT GERM
65
+ REF AACD-12345, 20 JUN 53
66
+ POB GERM, BERLIN 5
67
+ OCC PHARMACIST 6
68
+ OCC CODE CHEN
69
+ 201-0032671*
70
+ ΤΥΡΕ ΝΑΜE T-
71
+ ΟΙ CODES AA XX-10
72
+ RCD DATE 53.
73
+ SUBJECT RECENTLY ATTENDED THE SEVENTEENTH ANNUAL
74
+ CONFERENCE OF THE INTERNATIONAL ASSOCIATION OF CHEMISTS
75
+ AND PHARMACISTS HELD IN MUNICH, GERMANY FROM 22 THROUGH
76
+ 29 ОСТОВER.
77
+ 30 NOV 70
78
+ (3
79
+ Information About Subject
80
+ 1. Sequence Number and Name
81
+ 2. Sex and Date of Birth
82
+ 3. Citizenship
83
+ 4. Place of Birth
84
+ 5. Occupation
85
+ 6. Occupation Code
86
+ 7. Text
87
+ Document Reference Data Group
88
+ 8. 201 Number
89
+ 7
90
+ 9. Name Type Indicator
91
+ 10. OI Codes
92
+ 11. Record Date (year only)
93
+ 12. Reference
94
+ ISG Control Information
95
+ 13. Date of latest update of the record
96
+ 14. STAR Index Record Number
97
+ 24
98
+ SECRET
99
+ 00833555
100
+ 14
101
+ !
102
+ 14-00000
103
+ ( SECRET (
104
+ DOHB 70-1-1
105
+ CHAPTER III, ANNEX B
106
+ 15 November 1974
107
+ 7
108
+ e. Ol Code: a two letter symbol used in conjunction with the 201 per-
109
+ sonality records in the 201 system to record the association of an individual
110
+ with organizations or activities of operational interest. OI codes cover intelli-
111
+ gence and security service affiliation, whether staff or agent, or known or
112
+ suspect, as well as activities of DDO interest. There are two categories of OI
113
+ codes for use by components:
114
+
115
+ (1) general OI codes (Attachment 4)
116
+ (2) OI codes assigned to a specific component for intelligence services
117
+ or other specific organizations.
118
+
119
+ À component may request an OI code be established by submitting a mem-
120
+ orandum to the DDO/RMO through the component Records Management
121
+ Officer.
122
+
123
+ A 201 personality may be assigned two OI codes. An OI code may be assigned
124
+ when the 201 Personality File Action Request (Form 831) is initiated (see
125
+ paragraph 3b below) by filling in Box 13 or a code may be assigned or added
126
+ at a later date by a Form 831 amendment.
127
+
128
+ The 201 system has the capability of producing machine listings of 201
129
+ personalities by Of codes. For example, if an Ol code has been opened for the
130
+ security service of a certain country a listing may be compiled of all members
131
+ of that service.
132
+
133
+ f. 201 Machine Lists: produced from the mechanized 201 Index, based on
134
+ names or other identifying information of personalities on whom 201 dossiers
135
+ exist.
136
+
137
+ 3. OPENING A 201 DOSSIER
138
+
139
+ a. General
140
+
141
+ The opening of a 201 dossier is the prerogative of an operational com-
142
+ ponent, in coordination with the Information Services Group. An opening creates
143
+ a master 201 record. Changes to the master record and the occasional closing.
144
+ of a 201 dossier are controlled jointly by the desks and ISG. 201 dossiers may be
145
+ opened on persons who meet the carding criteria described in Chapter If of this
146
+ handbook, when there is a reasonable expectation that additional information
147
+ will be acquired and filed in such a dossier. Generally dossiers are opened on
148
+ persons about whom counterintelligence information is being reported, and per-
149
+ sons of operational interest to the Operations Directorate, specifically those
150
+ persons for whom provisional operational approvals and operational approvals
151
+ are requested (see exception below). 201 files are not to be opened on staff
152
+ employees, staff agents and most categories of contract employees. Files on
153
+
154
+ 25
155
+ SECRET
156
+ 14-00000
157
+
158
+ SECRET
159
+ (
160
+ DOHB 70-1-1
161
+ CHAPTER III, ANNEX B
162
+ 15 November 1974
163
+
164
+ persons who are only of local interest to a field station or Headquarters desk
165
+ and on whom no DDO records correspondence exists are not a part of the DDO
166
+ records system and are to be maintained by that unit. Some desks levy require-
167
+ ments on ISG for automatic 201 openings on certain categories of persons whose.
168
+ names appear in incoming dispatches. These are listed in Attachment 2. 201
169
+ dossiers should be opened in the following categories:
170
+
171
+ (1) Subjects of provisional operational approval and operational ap-
172
+ proval requests. However, a file need not be opened when a POA is requested
173
+ for persons being trained for a foreign liaison service and who are of opera-
174
+ tional interest for training purposes only.
175
+ اه
176
+
177
+ (2) Persons for whom the field requests a 201 opening.
178
+
179
+ (3) MHFIXTURE personalities: bonafide diplomats of other than
180
+ denied area countries, in close association with staff personnel.
181
+
182
+ (4) Subjects of a Personal Record Questionnaire Part I.
183
+
184
+ (5) Persons on whom a Main Index search reveals information in five
185
+ or more documents (see DOI 70-20).
186
+
187
+ (6) Subjects of Interagency Source Register memoranda from LSN/
188
+ ISR (opened only by IP/RMS).
189
+
190
+ b. Requesting a 201 File Opening
191
+
192
+ Headquarters desks may open a 201 file by filling out and submitting
193
+ a 201 Personality File Action Request (Form 831) to the Records Main-
194
+ tenance Section (IP/RMS). Form 831 is also used to create or amend the
195
+ master 201 record and 201 machine listings and to register the assign-
196
+ ment of a cryptonym to a 201 personality. Attachment 3 consists of sample
197
+ 201 Personality File Action Requests for opening and amending 201's. A field
198
+ station may request the opening of a 201 file by writing 201- in the Head-
199
+ quarters file or cross-reference box on the dispatch form and/or after the
200
+ subject's name in the body of the dispatch. A telepouch request for a 201 opening
201
+ is made by indicating 201- in the file number line. A cable request is made by
202
+ placing 201- after the term "File" on the last line of the transmission. IP/AN
203
+ will open 201 files as requested by dispatch or telepouch but it is the responsi-
204
+ bility of the desk to respond to cable requests. Field stations are notified of
205
+ 201 openings through receipt of the field master 201 record.
206
+
207
+ 28
208
+ SECRET
209
+ che kind while distribunal raudase andur, sinclarations . indian phính thi song
210
+ 14-00000
211
+ ( SECRET (
212
+ DOHB 70-1-1
213
+ CHAPTER III, ANNEX B
214
+ 15 November 1974
215
+
216
+ 4. CONTENTS OF THE DOSSIER
217
+
218
+ Information about a 201 personality should be filed or cross-referenced into
219
+ his dossier. When additional information is discovered on a 201 subject through
220
+ a name trace or other process, i.e., review of predecessor documents, it must
221
+ be consolidated into his personality dossier. See DOI 70-20 for consolidation
222
+ procedures.
223
+ ?
224
+ Material which is filed in the dossier includes but is not limited to:
225
+
226
+ a. 201 Personality File Action Request (Form 831).
227
+
228
+ b. Biographic information including photographs, fingerprints, and
229
+ handwriting samples.
230
+ 1.1
231
+ c. Personal Record Questionnaire Parts I and II.
232
+
233
+ d. Operational and other security approvals.
234
+
235
+ e. Name check replies, requests, clearances, and approvals.
236
+
237
+ f. Acknowledgement of pseudonym.
238
+
239
+ g. 201 personality assessments and evaluations.
240
+
241
+ h. Copy of contract and termination papers.
242
+
243
+ i. Secrecy agreement.
244
+
245
+ j. Agent Duty Status Report.
246
+
247
+ k. Training and evaluation.
248
+
249
+ 1. SGSWIRL report.
250
+
251
+ m. Newspaper clippings.
252
+
253
+ n. Any information which helps provide a better understanding of the
254
+ subject and our interest in him; this may include operational reporting:
255
+ :
256
+
257
+ 5. MAINTENANCE OF 201 DOSSIERS
258
+
259
+ The 201 personality dossier contains, in document date order, papers which
260
+ have been made a part of the Central Records System as well as those which
261
+ have not. Record documents may range from newspaper or magazine articles
262
+ on the subject to finance and other administrative papers.
263
+
264
+ 26,1
265
+ عت
266
+ SECRET
267
+ 14-00000
268
+ ( SECRET (
269
+ DOHB 70-1-1-4
270
+ CHAPTER III, ANNEX B
271
+ 15 November 1974
272
+
273
+ a. Purging
274
+ Purging a 201 dossier is the responsibility of the desk officer. It requires
275
+ discrimination in recognizing operationally useful material, rather than the
276
+ simple distinction between official and unofficial papers; it will therefore take
277
+ place under the supervision of a Records Officer. Purging should be done
278
+ periodically. A 201 dossier being forwarded to Central Files for retention should
279
+ be purged. A 201 dossier should be purged of the following:
280
+
281
+ (1) Duplicate material, i.e., exact copy(s) of a document.
282
+
283
+ (2) Name trace form (Form 362) unless it has been the basis for
284
+ the opening.
285
+
286
+ (3) All abstract slips.
287
+
288
+ (4) All document restriction notices (Form 1884).
289
+
290
+ (5) The disseminated version of positive intelligence information if
291
+ a copy of the raw report is contained in the 201 file; the dissemination number
292
+ then must be transferred to the first page of the raw report.
293
+
294
+ (6) Routing slips, routing and record sheets (Form 610) and dispatch
295
+ cover sheets unless there are remarks such as coordinations or comments.
296
+
297
+ (7) Record copy documents which only repeat substantive information
298
+ contained in other documents in the file; authorization for destruction is
299
+ by the Records Officer.
300
+
301
+ (8) Top Secret documents are not to be retained in a 201 dossier
302
+ forwarded to Central Files; the document must be downgraded for retention
303
+ in the 201 dossier. To downgrade a Top Secret document, an authorized
304
+ officer in the originating office or the Records Officer having jurisdiction
305
+ over the contents of the material must possess Top Secret classification-
306
+ authority. If the document cannot be downgraded the file should be retained
307
+ at the desk or the copy of the TS document should be removed, retained
308
+ in a desk TS file or forwarded to the Top Secret Control Officer, and a
309
+ cross-reference sheet (Form 867) placed in the 201 file giving the location
310
+ of the TS document.
311
+
312
+ (9) Deferred documents (see 5b(2)).
313
+
314
+ b. Maintenance Procedures
315
+
316
+ (1) All material in a 201 dossier will be filed in document date order.
317
+ In the case of document attachments which have been classified into a 201
318
+ 26.2
319
+ SECRET
320
+ 14-00000
321
+ SECRET (
322
+ DOHB 70-1-1
323
+ CHAPTER III, ANNEX B
324
+ 15 November 1974
325
+ 7
326
+ dossier and separated from the basic document by the assignment of a slash
327
+ number, the attachment will be filed by the date of the basic document.
328
+
329
+ (2) Deferred documents will not be filed in a 201 dossier. If they are
330
+ to be retained in the dossier they should be sent to IP/RMS for classification
331
+ into that 201.
332
+
333
+ (3) Field index cards (held by some desks) and area desk cards may
334
+ be retained in the 201 as part of a consolidation procedure. These cards
335
+ should be mounted on a full-size sheet of paper for filing in the 201..
336
+
337
+ (4) A 201 dossier previously opened on a person who becomes a staff
338
+ employee and which contains Record Copy documents will be restricted to
339
+ the ISG/DIP unless the desk retains the restriction. The dossier should be
340
+ closed if there are no Record Copy documents in it.
341
+
342
+ (5) A 201 opened in pseudonym should be consolidated into the true
343
+ name 201 if one exists or converted to the true name.
344
+
345
+ (6) Field and duplicate (shadow) (201 files no longer of active interest
346
+ should be incorporated into the official 201 after the duplicate material
347
+ has been purged by the desk officer and the remaining information classified
348
+ to that 201 by the Analysis Section (IP/AN).
349
+
350
+ (7) Any document with a predecessor organization cover sheet or an
351
+ OPC (Office of Policy Coordination) cover sheet from the Archives and
352
+ Disposition Section (IP/ARD) must be returned to IP/ARD for processing
353
+ to the 201.
354
+
355
+ (8) Desk memoranda (with or without a document source number)
356
+ containing substantive or derogatory information on the subject of the 201
357
+ should be sent to. IP/AN to be classified officially into the 201 file.
358
+
359
+ (9) An attachment which should be separated from its basic document
360
+ for inclusion in a-201 personality dossier will be forwarded with the basic
361
+ document to IP/AN for processing into the 201.
362
+
363
+ (10) To retain the P&L, RYBAT, or KAPOK sensitivity of a document
364
+ remaining in a 201 dossier being retired to Central Files, place that document
365
+ in an envelope sealed with black tape (see DOI 70-17). Any RYBAT, P&L,
366
+ or KAPOK document sent to Central Files not in a black-taped envelope will
367
+ automatically be handled as desensitized. A black-taped envelope may con-
368
+ tain only one document and must be filed in chronological order within the
369
+ file. If there are numerous documents of this type the desk officer may black--- v
370
+ tape the entire dossier rather than individual documents (see DOI 70-10).
371
+
372
+ 26.3
373
+ SECRET
374
+ 14-00000
375
+ SECRET
376
+ (
377
+ DOHB 70-1-14
378
+ CHAPTER III, ANNEX B
379
+ 15 November 1974
380
+
381
+ Black-taped dossiers or dossiers with black-taped documents will be
382
+ handled as restricted dossiers.
383
+
384
+ (11) An inactive 201 dossier or an inactive volume of a large 201
385
+ dossier on permanent charge should be returned to Central Files under a
386
+ Routing and Record Sheet with the notation shown below..
387
+
388
+ UNCLASSIFIED
389
+ INTERNAL
390
+ USE ONLY
391
+ SUBJECT:
392
+ FROM
393
+ TO O
394
+ 1.
395
+ IP/Files
396
+ CC-52
397
+ 2
398
+ 5.
399
+ 7.
400
+ L
401
+ CONFIDENTIAL
402
+ SECRET
403
+ ROUTING AND RECORD SHEET
404
+ TRANSMITTAL OF INACTIVE 201 DOSSIERS
405
+ DATE
406
+ OFFICERS COMMENTS eru samned to show ham sh
407
+ SHETLALS
408
+ (For guidance see CSHB 70-1-1,
409
+ Chapter III, Annex B.)
410
+ Volume(s) of volume(s)
411
+ of 201-
412
+ Restricted Dossier
413
+ (Attach Foru 2021 to
414
+ Dossier)
415
+ Non-Restricted Dossier
416
+ 10.
417
+ For Split Charge Dossiers:
418
+ 11.
419
+ All documents prior to
420
+ (date)
421
+ 12
422
+ 12
423
+ 14.
424
+ 15.
425
+ forvarded to IP/Files. All
426
+ documents after
427
+ retained at
428
+ BIDE
429
+ SECRET CONFIDENTIAL
430
+ PETERMAL
431
+ 28.4
432
+ SECRET
433
+ (date)
434
+ desk.
435
+ CL STA
436
+ UNCLASSIFIED
437
+ ::
438
+ 14-00000
439
+ ( SECRET (
440
+ DOHB 70-1-1
441
+ CHAPTER III, ANNEX B
442
+ 15 November 1974
443
+
444
+ 6. 201 DOSSIER CHARGES
445
+
446
+ A 201 dossier may be kept on permanent charge at the desk during any
447
+ period of active interest. If the dossier is transferred to another desk, the desk
448
+ officer who is transferring the dossier must notify Central Files of the transfer.
449
+ Central Files will then send the Notice of Transfer of Document or File Account-
450
+ ability (Form 2977) to the new action desk officer.
451
+ TO:
452
+ HAME
453
+ CONFIDENTIAL
454
+ (Thon gitled in)
455
+ NOTICE OF TRANSFER OF DOCUMENT OR FILE ACCOUNTABILITY
456
+ BADGE
457
+ COMPONENT
458
+ ROOM
459
+ TUDE
460
+ EXT.
461
+ This is to notify you that accountability for the document(s) and/or file(s) cited
462
+ below has been transferred to you by:
463
+ Accordingly, IP's records now reflect you as the custodian. Please contact IP/Files,
464
+ Ext. 4362, if you have any questions regarding this transfer.
465
+ SUBJECT OF REQUEST
466
+ FORM 2377E PREVIOUS COITIONS
467
+ 1-73
468
+ DATE
469
+ FILE NO.
470
+ DOC. STHSOL & NUMBER BOC. DATE
471
+ 40
472
+ TRANSFER
473
+ CHARGE
474
+ PERM
475
+ OR TENP
476
+ CONFIDENTIAL
477
+ CL BY: 007672
478
+ The new action desk officer must then fill out a 201 Personality File Action
479
+ Request (Form 813) to change the action desk designation to insure that the
480
+ 201 personality will be included in the Headquarters and field machine listings
481
+ for his component..
482
+
483
+ 7. RESTRICTED DOSSIERS
484
+
485
+ a. Access to a sensitive 201 dossier may be restricted by holding the file at the
486
+ desk or placing it on restriction in Central Files.
487
+
488
+ (1) The dossier may be restricted by checking Box 2 on the 201
489
+ Personality File Action Request (Form 831) when the file is opened.
490
+
491
+ 26.5
492
+ SECRET
493
+ :
494
+ :
495
+ 14-00000
496
+ ( SECRET (
497
+ DOHB 70-1-1
498
+ CHAPTER III, ANNEX B
499
+ 15 November 1974
500
+
501
+ (2) The dossier may be restricted by holding it on permanent charge
502
+ from Central Files. (Note: To maintain the restriction of a dossier being
503
+ returned to Central Files for retention, a File Restriction Notice (Form
504
+ 2021) must accompany the dossier.)
505
+
506
+ (3) The dossier may be restricted and held in Central Files by sub-
507
+ mitting a File Restriction Notice (Form 2021).
508
+ TO
509
+ IP/FI
510
+ GC-52 TUBE DT-6
511
+ IP/DCU
512
+ GC-40 TUBE HT-4
513
+ ACTION DESK: 1.
514
+ SECTION A
515
+ CONFIDENTIAL
516
+ (When Pilled In)
517
+ INITIALS
518
+ FILE RESTRICTION NOTICE
519
+ To restrict a file, complete Section A (signature of R.O. not
520
+ necessary).
521
+ 2. To remove a restriction, complete Section B (R.O. signature
522
+ Decessary).
523
+ FILE HUNGER
524
+ RESTRICT TO: (Use country or non-country code number. See CSI 70-28)
525
+ RESTRICTED BY:
526
+ COMPONENT:
527
+ Date:
528
+ SECTION B
529
+ REMOVE RESTRICTION (AUTHORIZED BY)
530
+ COMPONENT:
531
+ R.O. No.
532
+ Date:
533
+ FORN
534
+ 2-23 2021 IONS
535
+ CONFIDENTIAL
536
+ 8-2, IMPORT CL BY, CG7122
537
+ 7
538
+ b. Access to a restricted dossier located in Central Files is limited to the
539
+ personnel of the restricting desk or persons authorized by that desk. Any request
540
+ for the charge of a restricted dossier or any document within a restricted dossier
541
+ held in Central Files will be forwarded with the entire dossier and a multiple-
542
+ routed cover sheet to the restricting desk. This desk may then forward the file
543
+ to the requester or deny the request and return the dossier to Central Files. The
544
+ desk will notify the requester of a denial.
545
+
546
+ c. Anyone requesting a restricted dossier, or a document within a restricted
547
+ dossier, permanently or temporarily charged to a desk, will be referred to that
548
+ desk by Central Files.
549
+
550
+ 26.6
551
+ SECRET
552
+ 14-00000
553
+ ( SECRET (
554
+ DOHB 70-1-1
555
+ CHAPTER III, ANNEX B
556
+ 15 November 1974
557
+ ?
558
+ 8. REQUESTS FOR INFORMATION ON 201 PERSONALITIES
559
+
560
+ The Automated Index Section (IP/AIS) will provide the identity of the
561
+ subject of a 201 number unless the 201 file is restricted, in which case the
562
+ requester will be referred to the restricting desk.
563
+
564
+ IP/AIS will also provide the 201 number assigned to a name, unless the 201
565
+ file is restricted, or state that there is no 201 number assigned. Requesters should
566
+ supply identifying information whenever available for each name submitted.
567
+
568
+ `Requests pertaining to five or fewer names or numbers may be made by
569
+ telephone by calling the IP/AIS red line extension; IP/AIS will provide the
570
+ information by return call to the requester's extension as listed in the Badge
571
+ Table. Requests for more than five names or numbers must be listed and sent
572
+ by tube or courier to IP/AIS; IP/AIS will reply by return mail.
573
+
574
+ 9. 201 DOSSIER CANCELLATION
575
+
576
+ A 201 file may be authorized for cancellation by a Records Officer, after
577
+ appropriate coordination. The file should be forwarded to IP/RMS which will
578
+ destroy the folder and the cards leading to it and will remove the name and
579
+ number from machine lists. Any Record Copy document contained in the folder
580
+ will be reclassified to another appropriate file or sent to the Destruction Unit
581
+ (IP/DU) as directed by the desk Records Officer.
582
+
583
+ 10. 201 MACHINE LISTINGS
584
+
585
+ Machine listings provide field stations and Headquarters desks with names
586
+ and 201 numbers in the requester's particular geographic or functional area of
587
+ interest. If a component wishes to exclude a sensitive 201 personality from its
588
+ alphabetic, numeric, and cryptonym listings, this may be done when opening
589
+ the 201 or later by a 201 amendment. On the 201 Personality File Action Request
590
+ (Form 831) leave the country of location (Box 15) and interest desk (Box 16)
591
+ blank, use the non-country code 900 in the action box (Box -14), and indicate
592
+ permanent charge to the responsible desk. The only listing which will include the
593
+ 201 number is the IP/201 record for the Vital Records program. 201 listings are
594
+ categorized as standard or nonstandard and as scheduled or special.
595
+
596
+ a. Standard Listings
597
+
598
+ Issued semi-annually to Headquarters and the field; based on a component's
599
+ interest as indicated in the "Action Desk," "Country of Location," and "Interest
600
+
601
+ 28.7
602
+ SECRET
603
+ 14-00000
604
+
605
+ ( (
606
+ SECRET
607
+ DOHB 70-1-1
608
+ CHAPTER III, ANNEX B
609
+ 15 November 1974
610
+ **
611
+ Desk" blocks on the 201 Personality File Action Request (Form 831). The
612
+ standard listings available are:
613
+ i
614
+
615
+ (1) Alphabetical by surname, leading to a 201 number;
616
+
617
+ (2) Alphabetical by given name, leading to a 201 number;
618
+
619
+ (3) Alphabetical by cryptonym, leading to a 201 number;
620
+ ९.
621
+ i
622
+
623
+ (4) Numerical, leading to a surname;
624
+
625
+ (5) Numerical, leading to a cryptonym.
626
+ FUL & CHINA
627
+ 201 SURNAME ALPHA LIST
628
+ 03 ICT
629
+ 1973.
630
+ NAPIE
631
+ SECRET/ORGANIZATION INTERNAL USE ONLY
632
+ C, SH 117185/1343/5030/
633
+ CHEM. SHOU 117115/1343/0001/
634
+ CINE. SHU 1. 17115/1343/0001/
635
+ CHE. SHOU-JFY 16774/1108/0088
636
+ CHEM, SHOU EI
637
+ 17JUL14
638
+ BIRTHPLACE
639
+ DA/MO/YR
640
+ CERY GEFY
641
+ CHIN, RHANGTUNG
642
+ 4
643
+ 24 JANES
644
+ 90
645
+ CHIN, AMOY
646
+ 04JAN19
647
+ CHIN, FUXIEM, PROV.
648
+ A
649
+ 1240V22
650
+ CHIN, HUNムス
651
+ IPMARAS
652
+ CHIN
653
+ C41
654
+ CHIN, CAN ΤΩΝ
655
+ TYPE
656
+ 008
657
+ DCC. CIT. 201
658
+ 01-101-2. ACT. LOC. (ir.
659
+ MAME
660
+ CRAY
661
+ CIRY CE
662
+ CHINT 0165401
663
+ CHIN HR
664
+ DIPT
665
+ 0218859
666
+ CHIN CHIN
667
+ 5178653
668
+ CHEY
669
+ f-41G 17109/1343/690
670
+ CHAN. SIEU SHIH 17115/1105/001
671
+ CHFE SHCU-TAN
672
+ CHEY, SH-155467115/1109/1
673
+ CHEN, SHCU 126 /0701/1343/1807
674
+ CHEN, SHC-17115/1109/495
675
+ CHEM, SHU-٩٨١
676
+ CHY. SHAI-CHI4 17115/2005/6930
677
+ CHE: SHIU CINIAM 7115/3219/122
678
+ CHOM, SH-C17115/2535/2
679
+ CNCS. SITU 7115/2055/2797/ דניים
680
+ CHEN, SHU FEM
681
+ A
682
+ R
683
+ 0258926 CHIM, LEARNING PRO
684
+ 12JAN18
685
+ 09 JUN99
686
+ 1905619
687
+ 02 JUL 30
688
+ :
689
+ 19
690
+ NOV30
691
+ CIAC22
692
+ OF JUL 14
693
+ CHIN, FURIEN
694
+ CHIN, CAЧТО
695
+ CHIN, FLANGTING PROV
696
+ CHIN, KWANGTUNG PROV.
697
+ CHIN, FIJAN TANG IS
698
+ CHIN. PFILIU
699
+ CHIN, RAANG TUNG
700
+ ENGR CHAT 0832655
701
+ CHI47 0130415
702
+ CCC? 0091803
703
+ PROF CHIN? 0040289
704
+ CH417 0052638
705
+ ARMY CHAT 0328328
706
+ CHIN? 0124438
707
+ TSEA CRAT 0797335
708
+ 210CT06 CHIM, PANCINIPIA, PORT ARTH
709
+ BUSP CCOM? 0043751
710
+ CHAT 0179620
711
+ CHIN HK
712
+ CHIM? 0234629
713
+ :
714
+ CHIN CUSA
715
+ CHIN CHIN
716
+ CHAT
717
+ 0069786
718
+ CHIN
719
+ DIPT CCON
720
+ 0905340
721
+ CHIM MALT
722
+ :
723
+ CHIK HX
724
+ CHIR TAIW
725
+ CHIN
726
+ CHIN USA
727
+ CHEN HWA
728
+ CHER TAL
729
+ CHEN IK
730
+ CHIN H
731
+ CHIT, SMI HA /7113/2885/3185/
732
+ CFT, SITI HEANG 17115/2579/74
733
+ CFS-510 7115/2985/7
734
+ 10
735
+ 23FERO7
736
+ CHIN, FUKIEN
737
+ CHEN, KWANGTUNG
738
+ CIER, SHU MS
739
+ 17115/2835/8133
740
+ OSMAY18
741
+ CHIN, FOOCH
742
+ CHIT. SHU-درس
743
+ 30×4326
744
+ CHIEN SINI-1 2711.5/2925/5030/
745
+ A
746
+ 06F5816
747
+ CHIN, HOPET
748
+ CHIN? 0171622
749
+ DIPT CCCM. 0223161
750
+ CHIR USA
751
+ CHEN CHI
752
+ CHIN
753
+ CHIN CHIN
754
+ CHER USA
755
+ CHIN? 0200223
756
+ CHIN
757
+ 04RAST7
758
+ CHIN ETH
759
+ CHEY? 0179621
760
+ CHIK? 0014759
761
+ CCO? 00923195
762
+ CILEN
763
+ CHIN CEY
764
+ CHEN, SIRU RUET /7215/2695/2710
765
+ Girn, SIRI LAY
766
+ 27NQY23
767
+ CHIN. FANG CHIFING
768
+ PROF CHIN? 0175673
769
+ CHIM CHI
770
+
771
+ CHIN
772
+ CCON 0221972
773
+ CHIA CHI
774
+ CHLR, SIPI LIANG 77115/0547/009
775
+ CHEM. Sins 114 7115/2579/2631/
776
+ CIRCZE
777
+ CHIN
778
+ DEPT CHEN? 0223162
779
+ CHIN CHIN
780
+ 25MMV20-
781
+ CHIN, FERGSHUN
782
+ CHIN? 0179624
783
+ CHIM TAT
784
+ CHOEN SHIT-L145 17107/2473/010
785
+ 01 JUL 29
786
+ CHIN, FIANGSU
787
+ MILA CCM
788
+ 0834440
789
+ CHIM LACS
790
+ 20SE 20
791
+ CHER, HSIAM-HSLEN, KLANGSU
792
+ CHAT
793
+ 009647-
794
+ CHIN USA
795
+ CHEM, SHY 4/7119/2285/0589/
796
+ CILM, SHU-PAD 7115/2579/0202/
797
+ CHFA, SHU-SEM/7115/2895/2773/
798
+ CHIFT, SINI-SHAN 17115/2579/091
799
+ CHEM, SHU-TE /7115/2455/1795/
800
+ 154PR 30
801
+ 1°PECI
802
+ A
803
+ 300EC26
804
+ 27JAN25
805
+ 210EC37
806
+ CIPEN, SHU 1EH/475/
807
+ 27MA 20
808
+ CHEN, CHEHCHA 1
809
+ CHIN, KWANGTING PROV.
810
+ CHIM, KWANG TUPIG
811
+ CHIM, FUKIEN PROY
812
+ CHEN, SHANGHAI
813
+ CHIM, CHANG SHO
814
+ CHIN CHI
815
+ CHAT? 0052638
816
+ CHEN HWAL
817
+ CHINT 0085119
818
+ CHIN TATH
819
+ CHIN? OL03249
820
+ CHEN CHIN.
821
+ GEOL CHIN? 0763416-
822
+ CHEN BUSA
823
+ 0013991
824
+ CHIN
825
+ CM. SH15/0647/6639
826
+ CIPCTS
827
+ CHIN, HANG CHEA
828
+ CHIN? 0153929
829
+ OHER CAIR
830
+ CHEE, SHE T120 /7115/245/2757/
831
+ CICM. SU 1217:15/0647/0317 וי/
832
+ LAMAR17
833
+ CHEN:
834
+ FIN CCON0767442-CIA "UR
835
+ A
836
+ OZFEROS
837
+ 0151320
838
+ CHIN
839
+ CEA, S-T40/7115/2655/1031
840
+ CIPES, SM-T11
841
+ CHIR. SHIP 1/7115/2845/5341
842
+ CHIM, SIRI-19/7115/2579/6992/
843
+ アレった。ベリー
844
+ COUNT. SIN 7115/2579/3842/ ניז/
845
+ 11AOVOS
846
+ CHIN, RUENGTING
847
+ CHIN
848
+ OSAPRE?
849
+ CHIN, PEIPING
850
+ CHINT 0107306
851
+ CHIN CHEN
852
+ 15 JUNOG
853
+ CHEN, FARG CHET KU
854
+ CHIM? 0179624
855
+ CHIN CHIN
856
+ 0200130
857
+ 21APP21
858
+ CHIN, SHANGHAS
859
+ 04 SEP28
860
+ CHIS. SIECINAN
861
+ CHIN, HENG YANG HSIEN, HIJN ARMY-CHAT 0349624
862
+ 171FM38 CHIN. CHER LANG
863
+ SECRET/ORGANIZATION INTERNAL USE ONLY
864
+ 82 INPORS CL BY 056979
865
+ CHIN? 44010
866
+ CHIN? 0144758
867
+ CHIN TAIN
868
+ INT
869
+ 0111410
870
+ CHIN DEUX
871
+ CHIN
872
+ CHIM TAEw
873
+ PAGE
874
+ 150
875
+ 26.8
876
+ SECRET
877
+ 14-00000
878
+ ::
879
+ ( (
880
+ SECRET
881
+ DOHB 70-1-1
882
+ CHAPTER III, ANNEX B
883
+ 15 November 1974
884
+
885
+ All standard listings are cumulative; previous editions must be destroyed
886
+ upon receipt of current editions. These listings are by their very nature extremely
887
+ sensitive compilations of information and must be given every possible safeguard.
888
+
889
+ b. Non-Standard Listings
890
+ ?
891
+ :
892
+ Based on one or more of the following selection criteria:
893
+
894
+ (1) Country of location
895
+
896
+ (2) OI codes (organization and/or intelligence affiliation)
897
+
898
+ (3) Citizenship
899
+ ;
900
+
901
+ (4) Year of birth (plus or minus a given number of years)
902
+
903
+ (5) Occupation.
904
+
905
+ These selection criteria may be used singly or in combinations. For example,
906
+ a user could obtain a list of all 201 personalities who have been assigned the
907
+ OI code of XX or codes of XX, XY, or XZ. A