forked from GitHub/gf-core
scratched version of GWT Syntax Editor
This commit is contained in:
22
src/server/gwt/Editor-compile
Normal file
22
src/server/gwt/Editor-compile
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
APPDIR=`dirname $0`;
|
||||||
|
|
||||||
|
GWT_DIR="/home/angelov/gwt-linux-1.5.3"
|
||||||
|
GWT_CLASSPATH="$GWT_DIR/gwt-user.jar:$GWT_DIR/gwt-dev-linux.jar"
|
||||||
|
|
||||||
|
if [ -z "$GWT_CLASSPATH" ]; then
|
||||||
|
echo 'ERROR: $GWT_CLASSPATH is not set'
|
||||||
|
echo 'Set $GWT_CLASSPATH to point to the GWT JAR files. For example:'
|
||||||
|
echo 'export GWT_DIR="/Users/bringert/src/gwt-mac-1.5.2"'
|
||||||
|
echo 'export GWT_CLASSPATH="$GWT_DIR/gwt-user.jar:$GWT_DIR/gwt-dev-mac.jar"'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ `uname` = "Darwin" ]; then
|
||||||
|
GWT_JAVA_OPTS=-XstartOnFirstThread
|
||||||
|
fi
|
||||||
|
|
||||||
|
LIBS=$APPDIR/lib/gwt-dnd-2.5.6.jar
|
||||||
|
|
||||||
|
java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$LIBS:$GWT_CLASSPATH" com.google.gwt.dev.GWTCompiler -out "$APPDIR/www/editor" "$@" se.chalmers.cs.gf.gwt.EditorApp;
|
||||||
25
src/server/gwt/src/se/chalmers/cs/gf/gwt/EditorApp.gwt.xml
Normal file
25
src/server/gwt/src/se/chalmers/cs/gf/gwt/EditorApp.gwt.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<module>
|
||||||
|
|
||||||
|
<!-- Inherit the core Web Toolkit stuff. -->
|
||||||
|
<inherits name="com.google.gwt.user.User" />
|
||||||
|
<inherits name="com.google.gwt.xml.XML" />
|
||||||
|
|
||||||
|
<inherits name="se.chalmers.cs.gf.gwt.PGF" />
|
||||||
|
|
||||||
|
<!-- Inherit the default GWT style sheet. You can change -->
|
||||||
|
<!-- the theme of your GWT application by uncommenting -->
|
||||||
|
<!-- any one of the following lines. -->
|
||||||
|
<inherits name="com.google.gwt.user.theme.standard.Standard"/>
|
||||||
|
<!-- <inherits name="com.google.gwt.user.theme.chrome.Chrome"/> -->
|
||||||
|
<!-- <inherits name="com.google.gwt.user.theme.dark.Dark"/> -->
|
||||||
|
|
||||||
|
<!-- Other module inherits -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Specify the app entry point class. -->
|
||||||
|
<entry-point class="se.chalmers.cs.gf.gwt.client.EditorApp" />
|
||||||
|
|
||||||
|
<!-- Specify the application specific style sheet. -->
|
||||||
|
<stylesheet src="Editor.css" />
|
||||||
|
|
||||||
|
</module>
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
package se.chalmers.cs.gf.gwt.client;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.*;
|
||||||
|
import com.google.gwt.user.client.*;
|
||||||
|
import com.google.gwt.user.client.ui.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class AbstractSyntaxController {
|
||||||
|
private final Tree abstractTree;
|
||||||
|
private final FlowPanel textPanel;
|
||||||
|
|
||||||
|
private Map<Panel,TreeItem> panels;
|
||||||
|
private Map<TreeItem,List<Panel>> items;
|
||||||
|
|
||||||
|
private ClickListener labelClickListener;
|
||||||
|
|
||||||
|
private Panel focusPanel = null;
|
||||||
|
private Panel selectedPanel = null;
|
||||||
|
private TreeItem lastPanelItem = null;
|
||||||
|
|
||||||
|
public AbstractSyntaxController(final Tree abstractTree, final FlowPanel textPanel)
|
||||||
|
{
|
||||||
|
this.abstractTree = abstractTree;
|
||||||
|
this.textPanel = textPanel;
|
||||||
|
|
||||||
|
panels = new HashMap();
|
||||||
|
items = new HashMap();
|
||||||
|
|
||||||
|
abstractTree.addTreeListener(new TreeListener() {
|
||||||
|
public void onTreeItemSelected(TreeItem item)
|
||||||
|
{
|
||||||
|
focusPanel = selectedPanel;
|
||||||
|
|
||||||
|
for (Panel panel : panels.keySet())
|
||||||
|
{
|
||||||
|
panel.removeStyleDependentName("selected");
|
||||||
|
panel.removeStyleDependentName("focused");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Panel> panels = items.get(item);
|
||||||
|
if (panels != null)
|
||||||
|
{
|
||||||
|
for (Panel panel : panels)
|
||||||
|
{
|
||||||
|
String style = (panel == selectedPanel) ? "focused" : "selected";
|
||||||
|
panel.addStyleDependentName(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTreeItemStateChanged(TreeItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
labelClickListener = new ClickListener() {
|
||||||
|
public void onClick(Widget sender) {
|
||||||
|
Panel panel = (Panel) (sender.getParent());
|
||||||
|
|
||||||
|
TreeItem item = panels.get(panel);
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
selectedPanel = panel;
|
||||||
|
abstractTree.setSelectedItem(item);
|
||||||
|
abstractTree.ensureSelectedItemVisible();
|
||||||
|
selectedPanel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeItem addItem(String label)
|
||||||
|
{
|
||||||
|
TreeItem child = abstractTree.addItem(label);
|
||||||
|
addPanel(child, textPanel);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeItem addItem(TreeItem parent, String label)
|
||||||
|
{
|
||||||
|
TreeItem child = parent.addItem(label);
|
||||||
|
addPanel(child, getPanel(parent));
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Panel addPanel(TreeItem item, Panel parentPanel)
|
||||||
|
{
|
||||||
|
HorizontalPanel wordsPanel = new HorizontalPanel();
|
||||||
|
wordsPanel.setStylePrimaryName("my-WordsPanel");
|
||||||
|
panels.put(wordsPanel,item);
|
||||||
|
|
||||||
|
List<Panel> others = items.get(item);
|
||||||
|
if (others == null)
|
||||||
|
{
|
||||||
|
others = new ArrayList();
|
||||||
|
items.put(item,others);
|
||||||
|
}
|
||||||
|
others.add(wordsPanel);
|
||||||
|
|
||||||
|
parentPanel.add(wordsPanel);
|
||||||
|
|
||||||
|
lastPanelItem = item;
|
||||||
|
return wordsPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Panel getPanel(TreeItem item)
|
||||||
|
{
|
||||||
|
TreeItem tmpItem;
|
||||||
|
|
||||||
|
LinkedList<TreeItem> curr = new LinkedList();
|
||||||
|
tmpItem = item;
|
||||||
|
while (tmpItem != null)
|
||||||
|
{
|
||||||
|
curr.addFirst(tmpItem);
|
||||||
|
tmpItem = tmpItem.getParentItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkedList<TreeItem> last = new LinkedList();
|
||||||
|
tmpItem = lastPanelItem;
|
||||||
|
while (tmpItem != null)
|
||||||
|
{
|
||||||
|
last.addFirst(tmpItem);
|
||||||
|
tmpItem = tmpItem.getParentItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
TreeItem parent = null;
|
||||||
|
while (i < curr.size() && i < last.size())
|
||||||
|
{
|
||||||
|
if (curr.get(i) != last.get(i))
|
||||||
|
break;
|
||||||
|
|
||||||
|
parent = curr.get(i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Panel> others = items.get(parent);
|
||||||
|
if (others == null)
|
||||||
|
return null;
|
||||||
|
Panel panel = others.get(others.size()-1);
|
||||||
|
|
||||||
|
if (parent != item)
|
||||||
|
{
|
||||||
|
while (i < curr.size())
|
||||||
|
panel = addPanel(curr.get(i++), panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Label addWord(TreeItem item, String word)
|
||||||
|
{
|
||||||
|
Panel wordsPanel = getPanel(item);
|
||||||
|
|
||||||
|
Label wordLabel = new Label(word);
|
||||||
|
wordLabel.setStylePrimaryName("my-WordLabel");
|
||||||
|
wordLabel.addClickListener(labelClickListener);
|
||||||
|
|
||||||
|
wordsPanel.add(wordLabel);
|
||||||
|
|
||||||
|
return wordLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void edit()
|
||||||
|
{
|
||||||
|
if (focusPanel != null)
|
||||||
|
{
|
||||||
|
FlowPanel mainPanel = new FlowPanel();
|
||||||
|
mainPanel.add(new Magnet("fish","LangEng"));
|
||||||
|
mainPanel.add(new Magnet("beer","LangEng"));
|
||||||
|
mainPanel.add(new Magnet("cheese","LangEng"));
|
||||||
|
mainPanel.add(new Magnet("expensive","LangEng"));
|
||||||
|
mainPanel.add(new Magnet("delicious","LangEng"));
|
||||||
|
|
||||||
|
DecoratedPopupPanel completionPopup = new DecoratedPopupPanel(true);
|
||||||
|
completionPopup.addStyleName("my-FridgeBagPopup");
|
||||||
|
completionPopup.setWidget(mainPanel);
|
||||||
|
completionPopup.setPopupPosition(100, 100);
|
||||||
|
completionPopup.show();
|
||||||
|
|
||||||
|
final List<Widget> children = new ArrayList();
|
||||||
|
for (Widget widget : focusPanel)
|
||||||
|
{
|
||||||
|
children.add(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBox textBox = new TextBox();
|
||||||
|
textBox.setStylePrimaryName("my-TextEdit");
|
||||||
|
textBox.addFocusListener(new FocusListener() {
|
||||||
|
public void onFocus(Widget sender)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLostFocus(Widget sender)
|
||||||
|
{
|
||||||
|
focusPanel.clear();
|
||||||
|
for (Widget widget : children)
|
||||||
|
{
|
||||||
|
focusPanel.add(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
focusPanel.clear();
|
||||||
|
focusPanel.add(textBox);
|
||||||
|
textBox.setFocus(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
127
src/server/gwt/src/se/chalmers/cs/gf/gwt/client/EditorApp.java
Normal file
127
src/server/gwt/src/se/chalmers/cs/gf/gwt/client/EditorApp.java
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
package se.chalmers.cs.gf.gwt.client;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import com.google.gwt.core.client.*;
|
||||||
|
import com.google.gwt.user.client.*;
|
||||||
|
import com.google.gwt.user.client.ui.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class EditorApp implements EntryPoint {
|
||||||
|
|
||||||
|
private MenuBar createCommandsMenu(final AbstractSyntaxController absController)
|
||||||
|
{
|
||||||
|
// Create the commands menu
|
||||||
|
MenuBar menu = new MenuBar(true);
|
||||||
|
menu.addStyleName("my-CommandsMenu");
|
||||||
|
menu.setAutoOpen(true);
|
||||||
|
menu.setAnimationEnabled(true);
|
||||||
|
|
||||||
|
menu.addItem(new MenuItem("Undo", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Redo", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Cut", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Copy", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Paste", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Delete", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Refine", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Replace", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Wrap", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Parse", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
absController.edit();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Refine the node at random", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menu.addItem(new MenuItem("Refine the tree at random", new Command() {
|
||||||
|
public void execute() {
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populate(AbstractSyntaxController absController)
|
||||||
|
{
|
||||||
|
TreeItem sentenceItem = absController.addItem("Is : Phrase");
|
||||||
|
TreeItem item1 = absController.addItem(sentenceItem,"Det : ItemDet");
|
||||||
|
TreeItem item2 = absController.addItem(item1,"This : Item");
|
||||||
|
absController.addWord(item2,"this");
|
||||||
|
TreeItem item3 = absController.addItem(item1,"Cheese : Kind");
|
||||||
|
absController.addWord(item3,"cheese");
|
||||||
|
absController.addWord(item2,"and");
|
||||||
|
absController.addWord(item2,"only");
|
||||||
|
absController.addWord(item2,"this");
|
||||||
|
absController.addWord(sentenceItem,"is");
|
||||||
|
TreeItem item4 = absController.addItem(sentenceItem,"Expensive : Quality");
|
||||||
|
absController.addWord(item4,"expensive");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onModuleLoad() {
|
||||||
|
Tree abstractTree = new Tree();
|
||||||
|
abstractTree.addStyleName("my-AbstractTree");
|
||||||
|
|
||||||
|
FlowPanel textPanel = new FlowPanel();
|
||||||
|
|
||||||
|
ListBox choiceListBox = new ListBox();
|
||||||
|
choiceListBox.setVisibleItemCount(10);
|
||||||
|
choiceListBox.addStyleName("my-ChoiceListBox");
|
||||||
|
|
||||||
|
AbstractSyntaxController absController = new AbstractSyntaxController(abstractTree, textPanel);
|
||||||
|
|
||||||
|
VerticalSplitPanel vSplit = new VerticalSplitPanel();
|
||||||
|
vSplit.setSize("800px", "500px");
|
||||||
|
vSplit.setSplitPosition("52%");
|
||||||
|
|
||||||
|
HorizontalSplitPanel hSplit1 = new HorizontalSplitPanel();
|
||||||
|
hSplit1.setSplitPosition("22%");
|
||||||
|
hSplit1.setLeftWidget(new ScrollPanel(abstractTree));
|
||||||
|
hSplit1.setRightWidget(textPanel);
|
||||||
|
vSplit.setTopWidget(hSplit1);
|
||||||
|
|
||||||
|
HorizontalSplitPanel hSplit2 = new HorizontalSplitPanel();
|
||||||
|
hSplit2.setSplitPosition("22%");
|
||||||
|
hSplit2.setLeftWidget(createCommandsMenu(absController));
|
||||||
|
hSplit2.setRightWidget(choiceListBox);
|
||||||
|
vSplit.setBottomWidget(hSplit2);
|
||||||
|
|
||||||
|
populate(absController);
|
||||||
|
|
||||||
|
// Wrap the split panel in a decorator panel
|
||||||
|
DecoratorPanel decPanel = new DecoratorPanel();
|
||||||
|
decPanel.addStyleName("my-EditorPanel");
|
||||||
|
decPanel.setWidget(vSplit);
|
||||||
|
|
||||||
|
RootPanel.get().add(decPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
101
src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Editor.css
Normal file
101
src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Editor.css
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
body {
|
||||||
|
background: url("brushed-metal.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-WordsPanel {
|
||||||
|
float: left;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-WordsPanel-selected {
|
||||||
|
background-color: rgb(147,194,241);
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-WordsPanel-focused {
|
||||||
|
background-color: rgb(147,194,241);
|
||||||
|
border: 1px solid #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-WordLabel {
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-TextEdit {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid #666;
|
||||||
|
padding: none;
|
||||||
|
margin: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-ChoiceListBox {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-EditorPanel {
|
||||||
|
border: 1px solid #666;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-AbstractTree {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-AbstractTree .gwt-TreeItem {
|
||||||
|
cursor: hand;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-AbstractTree .gwt-TreeItem-selected {
|
||||||
|
background-color: #ffc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-CommandsMenu {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 80%;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-CommandsMenu .gwt-MenuItem {
|
||||||
|
cursor: hand;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-CommandsMenu .gwt-MenuItem-selected {
|
||||||
|
background-color: #ffc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-Magnet {
|
||||||
|
float: left;
|
||||||
|
margin: 0.3em;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: black;
|
||||||
|
padding: 0.3em;
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-Magnet {
|
||||||
|
float: left;
|
||||||
|
margin: 0.3em;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: black;
|
||||||
|
padding: 0.3em;
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-FridgeBagPopup {
|
||||||
|
padding: 0.2em;
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
36
src/server/gwt/www/editor/index.html
Normal file
36
src/server/gwt/www/editor/index.html
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<!-- The HTML 4.01 Transitional DOCTYPE declaration-->
|
||||||
|
<!-- above set at the top of the file will set -->
|
||||||
|
<!-- the browser's rendering engine into -->
|
||||||
|
<!-- "Quirks Mode". Replacing this declaration -->
|
||||||
|
<!-- with a "Standards Mode" doctype is supported, -->
|
||||||
|
<!-- but may lead to some differences in layout. -->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
|
<!-- -->
|
||||||
|
<!-- Any title is fine -->
|
||||||
|
<!-- -->
|
||||||
|
<title>Editor</title>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- This script loads your compiled module. -->
|
||||||
|
<!-- If you add any GWT meta tags, they must -->
|
||||||
|
<!-- be added before this line. -->
|
||||||
|
<!-- -->
|
||||||
|
<script type="text/javascript" language="javascript" src="se.chalmers.cs.gf.gwt.EditorApp/se.chalmers.cs.gf.gwt.EditorApp.nocache.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- The body can have arbitrary html, or -->
|
||||||
|
<!-- you can leave the body empty if you want -->
|
||||||
|
<!-- to create a completely dynamic UI. -->
|
||||||
|
<!-- -->
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- OPTIONAL: include this if you want history support -->
|
||||||
|
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user