picrate 2.0.0.pre-java → 2.2.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -1
  3. data/.mvn/wrapper/MavenWrapperDownloader.java +1 -1
  4. data/.mvn/wrapper/maven-wrapper.properties +2 -2
  5. data/CHANGELOG.md +10 -0
  6. data/README.md +11 -9
  7. data/Rakefile +9 -8
  8. data/docs/_config.yml +1 -1
  9. data/docs/_editors/geany.md +1 -0
  10. data/docs/_gems/gems/gems.md +1 -1
  11. data/docs/_methods/alternative_methods.md +2 -1
  12. data/docs/_posts/2018-05-06-getting_started.md +4 -4
  13. data/docs/_posts/2018-05-06-install_jruby.md +5 -11
  14. data/docs/_posts/2018-05-11-arch-linux-arm.md +1 -11
  15. data/docs/_posts/2018-11-18-building-gem.md +4 -2
  16. data/docs/_posts/2018-11-27-getting_started_geany.md +1 -1
  17. data/docs/_posts/2019-11-11-getting_started_buster.md +4 -7
  18. data/docs/_posts/{2018-06-26-auto_install_picrate.md → 2020-03-09-auto_install_picrate.md} +9 -6
  19. data/docs/_posts/2020-05-11-getting_started_manjaro.md +106 -0
  20. data/docs/about.md +1 -1
  21. data/lib/picrate.rb +2 -1
  22. data/lib/picrate/app.rb +1 -0
  23. data/lib/picrate/helper_methods.rb +1 -1
  24. data/lib/picrate/native_folder.rb +6 -7
  25. data/lib/picrate/runner.rb +4 -4
  26. data/lib/picrate/version.rb +1 -1
  27. data/library/jcomplex/jcomplex.rb +1 -0
  28. data/mvnw +2 -2
  29. data/mvnw.cmd +2 -2
  30. data/picrate.gemspec +3 -5
  31. data/pom.rb +18 -15
  32. data/pom.xml +20 -8
  33. data/src/main/java/monkstone/complex/JComplex.java +252 -0
  34. data/src/main/java/processing/awt/PGraphicsJava2D.java +22 -23
  35. data/src/main/java/processing/awt/PImageAWT.java +377 -0
  36. data/src/main/java/processing/awt/ShimAWT.java +545 -0
  37. data/src/main/java/processing/core/PApplet.java +2030 -2556
  38. data/src/main/java/processing/core/PGraphics.java +138 -124
  39. data/src/main/java/processing/core/PImage.java +1517 -1702
  40. data/src/main/java/processing/core/PSurface.java +105 -139
  41. data/src/main/java/processing/core/PSurfaceNone.java +29 -0
  42. data/src/main/java/processing/opengl/PGL.java +649 -3699
  43. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +223 -184
  44. data/src/main/java/processing/opengl/PJOGL.java +374 -1526
  45. data/src/main/java/processing/opengl/PShapeOpenGL.java +5 -6
  46. data/src/main/java/processing/opengl/PSurfaceJOGL.java +220 -86
  47. data/vendors/Rakefile +33 -21
  48. data/vendors/{picrate_sketches.geany → geany.rb} +32 -7
  49. metadata +17 -48
  50. data/src/main/java/processing/opengl/shaders/LightVert-brcm.glsl +0 -154
  51. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +0 -154
  52. data/src/main/java/processing/opengl/shaders/TexLightVert-brcm.glsl +0 -160
  53. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +0 -160
@@ -1756,7 +1756,7 @@ public class PShapeOpenGL extends PShape {
1756
1756
  }
1757
1757
 
1758
1758
  VertexAttribute attrib = polyAttribs.get(name);
1759
- float[] array = inGeo.fattribs.get(name);
1759
+ float[] array = (float[]) inGeo.fattribs.get(name);
1760
1760
  for (int i = 0; i < values.length; i++) {
1761
1761
  array[attrib.size * index + 0] = values[i];
1762
1762
  }
@@ -1772,7 +1772,7 @@ public class PShapeOpenGL extends PShape {
1772
1772
  }
1773
1773
 
1774
1774
  VertexAttribute attrib = polyAttribs.get(name);
1775
- int[] array = inGeo.iattribs.get(name);
1775
+ int[] array = (int[]) inGeo.iattribs.get(name);
1776
1776
  for (int i = 0; i < values.length; i++) {
1777
1777
  array[attrib.size * index + 0] = values[i];
1778
1778
  }
@@ -1788,7 +1788,7 @@ public class PShapeOpenGL extends PShape {
1788
1788
  }
1789
1789
 
1790
1790
  VertexAttribute attrib = polyAttribs.get(name);
1791
- byte[] array = inGeo.battribs.get(name);
1791
+ byte[] array = (byte[]) inGeo.battribs.get(name);
1792
1792
  for (int i = 0; i < values.length; i++) {
1793
1793
  array[attrib.size * index + 0] = (byte)(values[i]?1:0);
1794
1794
  }
@@ -3968,8 +3968,7 @@ public class PShapeOpenGL extends PShape {
3968
3968
  tessGeo.updateAttribBuffer(attrib.name);
3969
3969
  if (!attrib.bufferCreated()) attrib.createBuffer(pgl);
3970
3970
  pgl.bindBuffer(PGL.ARRAY_BUFFER, attrib.buf.glId);
3971
- pgl.bufferData(PGL.ARRAY_BUFFER, attrib.sizeInBytes(size),
3972
- tessGeo.polyAttribBuffers.get(name), glUsage);
3971
+ pgl.bufferData(PGL.ARRAY_BUFFER, attrib.sizeInBytes(size), (Buffer) tessGeo.polyAttribBuffers.get(name), glUsage);
3973
3972
  }
3974
3973
 
3975
3974
  pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
@@ -4333,7 +4332,7 @@ public class PShapeOpenGL extends PShape {
4333
4332
  protected void copyPolyAttrib(VertexAttribute attrib, int offset, int size) {
4334
4333
  tessGeo.updateAttribBuffer(attrib.name, offset, size);
4335
4334
  pgl.bindBuffer(PGL.ARRAY_BUFFER, attrib.buf.glId);
4336
- Buffer buf = tessGeo.polyAttribBuffers.get(attrib.name);
4335
+ Buffer buf = (Buffer) tessGeo.polyAttribBuffers.get(attrib.name);
4337
4336
  buf.position(attrib.size * offset);
4338
4337
  pgl.bufferSubData(PGL.ARRAY_BUFFER, attrib.sizeInBytes(offset),
4339
4338
  attrib.sizeInBytes(size), buf);
@@ -63,6 +63,10 @@ import com.jogamp.newt.awt.NewtCanvasAWT;
63
63
  import com.jogamp.newt.event.InputEvent;
64
64
  import com.jogamp.newt.opengl.GLWindow;
65
65
  import com.jogamp.opengl.util.FPSAnimator;
66
+ import java.awt.EventQueue;
67
+ import java.awt.FileDialog;
68
+ import processing.awt.PImageAWT;
69
+ import processing.awt.ShimAWT;
66
70
 
67
71
  import processing.core.PApplet;
68
72
  import processing.core.PConstants;
@@ -891,6 +895,148 @@ public class PSurfaceJOGL implements PSurface {
891
895
  });
892
896
  }
893
897
 
898
+ // TODO rewrite before 4.0 release
899
+ @Override
900
+ public PImage loadImage(String path, Object... args) {
901
+ return ShimAWT.loadImage(sketch, path, args);
902
+ }
903
+
904
+
905
+ @Override
906
+ public void selectInput(String prompt, String callbackMethod,
907
+ File file, Object callbackObject) {
908
+ EventQueue.invokeLater(() -> {
909
+ // https://github.com/processing/processing/issues/3831
910
+ boolean hide = (sketch != null) &&
911
+ (PApplet.platform == PConstants.WINDOWS);
912
+ if (hide) setVisible(false);
913
+
914
+ ShimAWT.selectImpl(prompt, callbackMethod, file,
915
+ callbackObject, null, FileDialog.LOAD);
916
+
917
+ if (hide) setVisible(true);
918
+ });
919
+ }
920
+
921
+
922
+ @Override
923
+ public void selectOutput(String prompt, String callbackMethod,
924
+ File file, Object callbackObject) {
925
+ EventQueue.invokeLater(() -> {
926
+ // https://github.com/processing/processing/issues/3831
927
+ boolean hide = (sketch != null) &&
928
+ (PApplet.platform == PConstants.WINDOWS);
929
+ if (hide) setVisible(false);
930
+
931
+ ShimAWT.selectImpl(prompt, callbackMethod, file,
932
+ callbackObject, null, FileDialog.SAVE);
933
+
934
+ if (hide) setVisible(true);
935
+ });
936
+ }
937
+
938
+
939
+ @Override
940
+ public void selectFolder(String prompt, String callbackMethod,
941
+ File file, Object callbackObject) {
942
+ EventQueue.invokeLater(() -> {
943
+ // https://github.com/processing/processing/issues/3831
944
+ boolean hide = (sketch != null) &&
945
+ (PApplet.platform == PConstants.WINDOWS);
946
+ if (hide) setVisible(false);
947
+
948
+ ShimAWT.selectFolderImpl(prompt, callbackMethod, file,
949
+ callbackObject, null);
950
+
951
+ if (hide) setVisible(true);
952
+ });
953
+ }
954
+
955
+ @Override
956
+ public void setCursor(int kind) {
957
+ if (!cursorNames.containsKey(kind)) {
958
+ PGraphics.showWarning("Unknown cursor type: " + kind);
959
+ return;
960
+ }
961
+ CursorInfo cursor = cursors.get(kind);
962
+ if (cursor == null) {
963
+ String name = cursorNames.get(kind);
964
+ if (name != null) {
965
+ ImageIcon icon =
966
+ new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
967
+ PImage img = new PImageAWT(icon.getImage());
968
+ // Most cursors just use the center as the hotspot...
969
+ int x = img.width / 2;
970
+ int y = img.height / 2;
971
+ // ...others are more specific
972
+ switch (kind) {
973
+ case PConstants.ARROW:
974
+ x = 10;
975
+ y = 7;
976
+ break;
977
+ case PConstants.HAND:
978
+ x = 12;
979
+ y = 8;
980
+ break;
981
+ case PConstants.TEXT:
982
+ x = 16;
983
+ y = 22;
984
+ break;
985
+ default:
986
+ break;
987
+ }
988
+ cursor = new CursorInfo(img, x, y);
989
+ cursors.put(kind, cursor);
990
+ }
991
+ }
992
+ if (cursor != null) {
993
+ cursor.set();
994
+ } else {
995
+ PGraphics.showWarning("Cannot load cursor type: " + kind);
996
+ }
997
+ }
998
+
999
+
1000
+ @Override
1001
+ public void setCursor(PImage image, int hotspotX, int hotspotY) {
1002
+ Display disp = window.getScreen().getDisplay();
1003
+ BufferedImage bimg = (BufferedImage)image.getNative();
1004
+ DataBufferInt dbuf = (DataBufferInt)bimg.getData().getDataBuffer();
1005
+ int[] ipix = dbuf.getData();
1006
+ ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
1007
+ pixels.asIntBuffer().put(ipix);
1008
+ PixelFormat format = PixelFormat.ARGB8888;
1009
+ final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
1010
+ PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
1011
+ final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
1012
+ display.getEDTUtil().invoke(false, () -> {
1013
+ window.setPointerVisible(true);
1014
+ window.setPointerIcon(pi);
1015
+ });
1016
+ }
1017
+
1018
+
1019
+ @Override
1020
+ public void showCursor() {
1021
+ display.getEDTUtil().invoke(false, () -> {
1022
+ window.setPointerVisible(true);
1023
+ });
1024
+ }
1025
+
1026
+
1027
+ @Override
1028
+ public void hideCursor() {
1029
+ display.getEDTUtil().invoke(false, () -> {
1030
+ window.setPointerVisible(false);
1031
+ });
1032
+ }
1033
+
1034
+
1035
+ @Override
1036
+ public boolean openLink(String url) {
1037
+ return ShimAWT.openLink(url);
1038
+ }
1039
+
894
1040
  class DrawListener implements GLEventListener {
895
1041
 
896
1042
  @Override
@@ -1353,24 +1499,24 @@ public class PSurfaceJOGL implements PSurface {
1353
1499
  return def;
1354
1500
  }
1355
1501
 
1356
- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1357
- class CursorInfo {
1358
1502
 
1359
- PImage image;
1360
- int x, y;
1361
1503
 
1362
- CursorInfo(PImage image, int x, int y) {
1363
- this.image = image;
1364
- this.x = x;
1365
- this.y = y;
1366
- }
1504
+ class CursorInfo {
1505
+ PImage image;
1506
+ int x, y;
1367
1507
 
1368
- void set() {
1369
- setCursor(image, x, y);
1370
- }
1508
+ CursorInfo(PImage image, int x, int y) {
1509
+ this.image = image;
1510
+ this.x = x;
1511
+ this.y = y;
1371
1512
  }
1372
1513
 
1373
- static Map<Integer, CursorInfo> cursors = new HashMap<>();
1514
+ void set() {
1515
+ setCursor(image, x, y);
1516
+ }
1517
+ }
1518
+
1519
+ static Map<Integer, CursorInfo> cursors = new HashMap<>();
1374
1520
  static Map<Integer, String> cursorNames = Map.of(
1375
1521
  PConstants.ARROW, "arrow",
1376
1522
  PConstants.CROSS, "cross",
@@ -1381,79 +1527,67 @@ public class PSurfaceJOGL implements PSurface {
1381
1527
  );
1382
1528
 
1383
1529
 
1384
- @Override
1385
- public void setCursor(int kind) {
1386
- if (!cursorNames.containsKey(kind)) {
1387
- PGraphics.showWarning("Unknown cursor type: " + kind);
1388
- return;
1389
- }
1390
- CursorInfo cursor = cursors.get(kind);
1391
- if (cursor == null) {
1392
- String name = cursorNames.get(kind);
1393
- if (name != null) {
1394
- ImageIcon icon
1395
- = new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
1396
- PImage img = new PImage(icon.getImage());
1397
- // Most cursors just use the center as the hotspot...
1398
- int x = img.width / 2;
1399
- int y = img.height / 2;
1400
- // ...others are more specific
1401
- switch (kind) {
1402
- case PConstants.ARROW:
1403
- x = 10;
1404
- y = 7;
1405
- break;
1406
- case PConstants.HAND:
1407
- x = 12;
1408
- y = 8;
1409
- break;
1410
- case PConstants.TEXT:
1411
- x = 16;
1412
- y = 22;
1413
- break;
1414
- default:
1415
- break;
1416
- }
1417
- cursor = new CursorInfo(img, x, y);
1418
- cursors.put(kind, cursor);
1419
- }
1420
- }
1421
- if (cursor != null) {
1422
- cursor.set();
1423
- } else {
1424
- PGraphics.showWarning("Cannot load cursor type: " + kind);
1425
- }
1426
- }
1427
-
1428
- @Override
1429
- public void setCursor(PImage image, int hotspotX, int hotspotY) {
1430
- Display disp = window.getScreen().getDisplay();
1431
- BufferedImage bimg = (BufferedImage) image.getNative();
1432
- DataBufferInt dbuf = (DataBufferInt) bimg.getData().getDataBuffer();
1433
- int[] ipix = dbuf.getData();
1434
- ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
1435
- pixels.asIntBuffer().put(ipix);
1436
- PixelFormat format = PixelFormat.ARGB8888;
1437
- final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
1438
- PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
1439
- final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
1440
- display.getEDTUtil().invoke(false, () -> {
1441
- window.setPointerVisible(true);
1442
- window.setPointerIcon(pi);
1443
- });
1444
- }
1530
+ // @Override
1531
+ // public void setCursor(int kind) {
1532
+ // if (!cursorNames.containsKey(kind)) {
1533
+ // PGraphics.showWarning("Unknown cursor type: " + kind);
1534
+ // return;
1535
+ // }
1536
+ // CursorInfo cursor = cursors.get(kind);
1537
+ // if (cursor == null) {
1538
+ // String name = cursorNames.get(kind);
1539
+ // if (name != null) {
1540
+ // ImageIcon icon
1541
+ // = new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
1542
+ // PImage img = new PImage(icon.getImage());
1543
+ // // Most cursors just use the center as the hotspot...
1544
+ // int x = img.width / 2;
1545
+ // int y = img.height / 2;
1546
+ // // ...others are more specific
1547
+ // switch (kind) {
1548
+ // case PConstants.ARROW:
1549
+ // x = 10;
1550
+ // y = 7;
1551
+ // break;
1552
+ // case PConstants.HAND:
1553
+ // x = 12;
1554
+ // y = 8;
1555
+ // break;
1556
+ // case PConstants.TEXT:
1557
+ // x = 16;
1558
+ // y = 22;
1559
+ // break;
1560
+ // default:
1561
+ // break;
1562
+ // }
1563
+ // cursor = new CursorInfo(img, x, y);
1564
+ // cursors.put(kind, cursor);
1565
+ // }
1566
+ // }
1567
+ // if (cursor != null) {
1568
+ // cursor.set();
1569
+ // } else {
1570
+ // PGraphics.showWarning("Cannot load cursor type: " + kind);
1571
+ // }
1572
+ // }
1573
+ //
1574
+ // @Override
1575
+ // public void setCursor(PImage image, int hotspotX, int hotspotY) {
1576
+ // Display disp = window.getScreen().getDisplay();
1577
+ // BufferedImage bimg = (BufferedImage) image.getNative();
1578
+ // DataBufferInt dbuf = (DataBufferInt) bimg.getData().getDataBuffer();
1579
+ // int[] ipix = dbuf.getData();
1580
+ // ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
1581
+ // pixels.asIntBuffer().put(ipix);
1582
+ // PixelFormat format = PixelFormat.ARGB8888;
1583
+ // final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
1584
+ // PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
1585
+ // final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
1586
+ // display.getEDTUtil().invoke(false, () -> {
1587
+ // window.setPointerVisible(true);
1588
+ // window.setPointerIcon(pi);
1589
+ // });
1590
+ // }
1445
1591
 
1446
- @Override
1447
- public void showCursor() {
1448
- display.getEDTUtil().invoke(false, () -> {
1449
- window.setPointerVisible(true);
1450
- });
1451
- }
1452
1592
 
1453
- @Override
1454
- public void hideCursor() {
1455
- display.getEDTUtil().invoke(false, () -> {
1456
- window.setPointerVisible(false);
1457
- });
1458
- }
1459
1593
  }
@@ -2,12 +2,13 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'rake/clean'
5
+ require_relative './geany'
5
6
  WARNING = 'WARNING: wget download failed you could do a manual download'
6
7
  SOUND = 'sound.zip'
7
- SOUND_VERSION = 'v1.3.2'
8
- VIDEO = 'video-2.0-beta4.zip'
9
- VIDEO_VERSION = 'r6-v2.0-beta4'
10
- EXAMPLES = '0.5.2'
8
+ PROCESSING_GITHUB = 'https://github.com/processing'
9
+ VIDEO = 'video.zip'
10
+ DOWNLOAD = 'releases/download/latest'
11
+ EXAMPLES = '0.5.5'
11
12
  HOME_DIR = ENV['HOME']
12
13
  LIBRARY = File.join(HOME_DIR, '.picrate', 'libraries')
13
14
  PROJECT_DIR = File.join(HOME_DIR, 'projects')
@@ -46,16 +47,24 @@ task download_samples: ["#{EXAMPLES}.tar.gz"]
46
47
 
47
48
  desc 'download sound library'
48
49
  task :download_sound do
49
- wget_base = 'wget -P https://github.com/processing/processing-sound'
50
- wget_string = [wget_base, 'releases/download/latest', SOUND].join('/')
51
- system wget_string
50
+ wget_base = ['wget', PROCESSING_GITHUB].join(' ')
51
+ wget_string = [wget_base, 'processing-sound', DOWNLOAD, SOUND].join('/')
52
+ begin
53
+ sh wget_string
54
+ rescue StandardError
55
+ warn(WARNING)
56
+ end
52
57
  end
53
58
 
54
59
  desc 'download video library'
55
60
  task :download_video do
56
- wget_base = 'wget -P /tmp https://github.com/processing/processing-video'
57
- wget_string = [wget_base, 'releases/download', VIDEO_VERSION, VIDEO].join('/')
58
- system wget_string
61
+ wget_base = ['wget', PROCESSING_GITHUB].join(' ')
62
+ wget_string = [wget_base, 'processing-video', DOWNLOAD, VIDEO].join('/')
63
+ begin
64
+ sh wget_string
65
+ rescue StandardError
66
+ warn(WARNING)
67
+ end
59
68
  end
60
69
 
61
70
  desc 'initialize ~/.picrate directories'
@@ -69,9 +78,11 @@ task :install_config do
69
78
  FileUtils.mkdir_p "#{HOME_DIR}/.config/geany/templates/files"
70
79
  FileUtils.cp 'picrate.rb', "#{HOME_DIR}/.config/geany/templates/files"
71
80
  end
72
- unless File.exist? "#{HOME_DIR}/projects/sketchbook/picrate_sketches.geany"
73
- FileUtils.mkdir_p "#{HOME_DIR}/projects/sketchbook"
74
- FileUtils.cp 'picrate_sketches.geany', "#{HOME_DIR}/projects/sketchbook"
81
+ project_dir = File.join(HOME_DIR, 'projects')
82
+ unless File.exist? File.join(project_dir, 'picrate_sketches.geany')
83
+ FileUtils.mkdir_p "#{HOME_DIR}/projects"
84
+ config = GeanyConfig.new(project_dir)
85
+ config.save(File.join(project_dir, 'picrate_sketches.geany'))
75
86
  end
76
87
  end
77
88
 
@@ -86,15 +97,16 @@ end
86
97
 
87
98
  desc 'copy sound library'
88
99
  task copy_sound: SOUND do
89
- system "unzip -d /tmp /tmp/#{SOUND}"
90
- FileUtils.rm_r "#{LIBRARY}/sound" if File.exist? "#{LIBRARY}/sound"
91
- FileUtils.cp_r '/tmp/sound', LIBRARY
100
+ sh "unzip #{SOUND}"
101
+ sh "rm -r #{LIBRARY}/sound" if File.exist? "#{LIBRARY}/sound"
102
+ sh "cp -r sound #{LIBRARY}"
103
+ sh 'rm -r sound'
92
104
  end
93
105
 
94
106
  desc 'copy video library'
95
- task copy_video: "/tmp/#{VIDEO}" do
96
- system "unzip -d /tmp /tmp/#{VIDEO}"
97
- FileUtils.rm_r "#{LIBRARY}/video" if File.exist? "#{LIBRARY}/video"
98
- FileUtils.mkdir_p "#{LIBRARY}/video/library"
99
- FileUtils.mv Dir.glob('/tmp/video/library/*.jar'), "#{LIBRARY}/video/library"
107
+ task copy_video: VIDEO do
108
+ sh "unzip #{VIDEO}"
109
+ sh "rm -r #{LIBRARY}/video" if File.exist? "#{LIBRARY}/video"
110
+ sh "cp -r video #{LIBRARY}"
111
+ sh 'rm -r video'
100
112
  end