cpee-frames 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,539 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # This file is part of CPEE-FRAMES.
4
+ #
5
+ # CPEE-FRAMES is free software: you can redistribute it and/or
6
+ # modify it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or (at your
8
+ # option) any later version.
9
+ #
10
+ # CPEE-FRAMES is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13
+ # Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along with
16
+ # CPEE-FRAMES (file LICENSE in the main directory). If not, see
17
+ # <http://www.gnu.org/licenses/>.
18
+
19
+ require 'rubygems'
20
+ require 'json'
21
+ require 'xml/smart'
22
+ require 'riddl/server'
23
+ require 'fileutils'
24
+ require 'typhoeus'
25
+
26
+ module CPEE
27
+
28
+ module Frames
29
+
30
+ SERVER = File.expand_path(File.join(__dir__,'frames.xml'))
31
+
32
+ # https://coderwall.com/p/atyfyq/ruby-string-to-boolean
33
+ # showbutton
34
+ refine String do #{{{
35
+ def to_bool
36
+ return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
37
+ return false if self == false || self.empty? || self =~ (/(false|f|no|n|0)$/i)
38
+ raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
39
+ end
40
+ end #}}}
41
+
42
+ class GetTutorial < Riddl::Implementation #{{{
43
+ def response
44
+ Riddl::Parameter::Complex.new('ui','text/html',File.open(File.join(__dir__,'ui','tutorial.html')))
45
+ end
46
+ end #}}}
47
+
48
+ class GetAllConfigs < Riddl::Implementation #{{{
49
+ def response
50
+ data_dir = @a[0]
51
+ databack = JSON::pretty_generate(Dir.glob(File.join(data_dir,'*')).map{|f| File.basename(f)}.sort_by{|x| x.downcase})
52
+ Riddl::Parameter::Complex.new('list','application/json',databack)
53
+ end
54
+ end #}}}
55
+
56
+ class Get < Riddl::Implementation #{{{
57
+ def response
58
+ if @r[0] == 'test'
59
+ Riddl::Parameter::Complex.new('ui','text/html',File.open(File.join(__dir__,'ui','test.html')))
60
+ elsif @r[0] == 'menu'
61
+ Riddl::Parameter::Complex.new('ui','text/html',File.open(File.join(__dir__,'ui','menu.html')))
62
+ elsif @r[0] == 'framedata'
63
+ Riddl::Parameter::Complex.new('ui','text/html',File.open(File.join(__dir__,'ui','framedata.html')))
64
+ else
65
+ Riddl::Parameter::Complex.new('ui','text/html',File.open(File.join(__dir__,'ui','template.html')))
66
+ end
67
+ end
68
+ end #}}}
69
+
70
+ class InitFrame < Riddl::Implementation #{{{
71
+ def response
72
+ Dir.mkdir(File.join('data',@r.last)) rescue nil
73
+
74
+ if !@p[0].value.to_s.empty?
75
+ File.write(File.join('data',@r.last,'style.url'),@p[0].value)
76
+ end
77
+
78
+ File.write(File.join('data',@r.last,'frames.json'),JSON.dump(JSON.parse('{"data":[]}')))
79
+
80
+ #for handler
81
+ File.write(File.join('data',@r.last,'dataelements.json'),JSON.dump(JSON.parse('{"data":[]}')))
82
+
83
+ File.write(File.join('data',@r.last,'info.json'),JSON.dump(JSON.parse('{"x_amount":' + @p[2].value + ', "y_amount":' + @p[3].value + ', "lang":"' + @p[4].value + '", "langs":["' + @p[4].value + '"], "document_name": "' + @p[5].value + '"}')))
84
+
85
+ File.write(File.join('data',@r.last,'callback'),@h['CPEE_CALLBACK'])
86
+ File.write(File.join('data',@r.last,'cpeeinstance.url'),@h['CPEE_INSTANCE_URL'])
87
+
88
+ @a[0].send('new')
89
+ nil
90
+ end
91
+ end #}}}
92
+
93
+ class NewFrameSet < Riddl::Implementation
94
+ def response
95
+ path = File.join('data',@r.last,'frames.json')
96
+ file = File.read(path)
97
+ data_hash = JSON::parse(file)
98
+
99
+ #check if new frame overlaps others if it does, delete overlapped frames
100
+ data_hash["data"].each do | c |
101
+ if doOverlap(c['lx'], c['ly'], c['rx'], c['ry'], @p[1].value.to_i, @p[2].value.to_i, (@p[1].value.to_i + @p[3].value.to_i - 1), (@p[2].value.to_i + @p[4].value.to_i - 1))
102
+ data_hash["data"].delete(c)
103
+ end
104
+ end
105
+
106
+ #check if url is set
107
+ if @p[7].value != ""
108
+ urls = JSON::parse(@p[7].value);
109
+
110
+ if @p[8].value == ""
111
+ hash = {lx: @p[1].value.to_i, ly: @p[2].value.to_i, rx: (@p[1].value.to_i + @p[3].value.to_i - 1), ry: (@p[2].value.to_i + @p[4].value.to_i - 1), url: urls, showbutton: @p[5].value, style: @p[6].value, default: "{}", callback: @h['CPEE_CALLBACK']};
112
+ else
113
+ hash = {lx: @p[1].value.to_i, ly: @p[2].value.to_i, rx: (@p[1].value.to_i + @p[3].value.to_i - 1), ry: (@p[2].value.to_i + @p[4].value.to_i - 1), url: urls, showbutton: @p[5].value, style: @p[6].value, default: JSON::parse(@p[8].value), callback: @h['CPEE_CALLBACK']};
114
+ end
115
+
116
+ data_hash["data"].push(hash)
117
+ File.write(path, JSON.dump(data_hash))
118
+
119
+ #only send active url to client
120
+ infofile = File.join('data',@r.last,'info.json')
121
+ infojson = JSON::parse(File.read(infofile))
122
+ hash["url"] = urls.find{ |h| h['lang'] == infojson["lang"]}['url']
123
+
124
+
125
+ @a[0].send(JSON.dump(hash))
126
+ else
127
+ File.write(path, JSON.dump(data_hash))
128
+ hash = {lx: @p[1].value.to_i, ly: @p[2].value.to_i, rx: (@p[1].value.to_i + @p[3].value.to_i - 1), ry: (@p[2].value.to_i + @p[4].value.to_i - 1), url: "empty", showbutton: @p[5].value, style: @p[6].value, default: "{}", callback: @h['CPEE_CALLBACK']};
129
+
130
+
131
+ @a[0].send(JSON.dump(hash))
132
+ end
133
+
134
+ nil
135
+ end
136
+ end
137
+
138
+ class NewFrameWait < Riddl::Implementation
139
+ def response
140
+ path = File.join('data',@r.last,'frames.json')
141
+ file = File.read(path)
142
+ data_hash = JSON::parse(file)
143
+
144
+ #check if new frame overlaps others if it does, delete overlapped frames
145
+ data_hash["data"].each do | c |
146
+ if doOverlap(c['lx'], c['ly'], c['rx'], c['ry'], @p[1].value.to_i, @p[2].value.to_i, (@p[1].value.to_i + @p[3].value.to_i - 1), (@p[2].value.to_i + @p[4].value.to_i - 1))
147
+ data_hash["data"].delete(c)
148
+ end
149
+ end
150
+
151
+
152
+ #check if url is set
153
+ if @p[7].value != ""
154
+ urls = JSON::parse(@p[7].value);
155
+ if @p[8].value == ""
156
+ hash = {lx: @p[1].value.to_i, ly: @p[2].value.to_i, rx: (@p[1].value.to_i + @p[3].value.to_i - 1), ry: (@p[2].value.to_i + @p[4].value.to_i - 1), url: urls, showbutton: @p[5].value, style: @p[6].value, default: "{}", callback: @h['CPEE_CALLBACK']};
157
+ else
158
+ hash = {lx: @p[1].value.to_i, ly: @p[2].value.to_i, rx: (@p[1].value.to_i + @p[3].value.to_i - 1), ry: (@p[2].value.to_i + @p[4].value.to_i - 1), url: urls, showbutton: @p[5].value, style: @p[6].value, default: JSON::parse(@p[8].value), callback: @h['CPEE_CALLBACK']};
159
+ end
160
+ data_hash["data"].push(hash)
161
+ File.write(path, JSON.dump(data_hash))
162
+
163
+ #only send active url to client
164
+ infofile = File.join('data',@r.last,'info.json')
165
+ infojson = JSON::parse(File.read(infofile))
166
+ hash["url"] = urls.find{ |h| h['lang'] == infojson["lang"]}['url']
167
+
168
+ File.write(File.join('data',@r.last,'callback'),@h['CPEE_CALLBACK'])
169
+
170
+
171
+ @a[0].send(JSON.dump(hash))
172
+ else
173
+ File.write(path, JSON.dump(data_hash))
174
+ hash = {lx: @p[1].value.to_i, ly: @p[2].value.to_i, rx: (@p[1].value.to_i + @p[3].value.to_i - 1), ry: (@p[2].value.to_i + @p[4].value.to_i - 1), url: "empty", showbutton: @p[5].value, style: @p[6].value, default: "{}", callback: @h['CPEE_CALLBACK']};
175
+
176
+ File.write(File.join('data',@r.last,'callback'),@h['CPEE_CALLBACK'])
177
+
178
+
179
+ @a[0].send(JSON.dump(hash))
180
+
181
+ Typhoeus.put(@h['CPEE_CALLBACK'], body: "No Frame Set")
182
+ end
183
+ nil
184
+
185
+ end
186
+ def headers
187
+ Riddl::Header.new('CPEE-CALLBACK', 'true')
188
+ end
189
+ end
190
+
191
+ class DeleteFrame < Riddl::Implementation
192
+ def response
193
+ path = File.join('data',@r.last,'frames.json')
194
+ file = File.read(path)
195
+ data_hash = JSON::parse(file)
196
+
197
+ data_hash["data"].each do | c |
198
+ if doOverlap(c['lx'], c['ly'], c['rx'], c['ry'], @p[0].value.to_i, @p[1].value.to_i, (@p[0].value.to_i + 1), (@p[1].value.to_i + 1))
199
+ data_hash["data"].delete(c)
200
+ end
201
+ end
202
+
203
+ File.write(path, JSON.dump(data_hash))
204
+ end
205
+ end
206
+
207
+ def doOverlap(l1x, l1y, r1x, r1y, l2x, l2y, r2x, r2y)
208
+ if l1x > r2x || l2x > r1x
209
+ return false;
210
+ end
211
+ if l1y > r2y || l2y > r1y
212
+ return false;
213
+ end
214
+ return true;
215
+ end
216
+
217
+ class Delete < Riddl::Implementation
218
+ def response
219
+ pp "in delete"
220
+ if cbu = File.read(File.join('data',@r.last,'callback'))
221
+ pp "XYZ"
222
+ send = { 'operation' => @p[0].value }
223
+ case send['operation']
224
+ when 'result'
225
+ send['target'] = JSON::parse(@p[1].value.read)
226
+ end
227
+ cbu += '/' unless cbu[-1] == '/'
228
+ pp "Sending"
229
+ Typhoeus.put(cbu, body: JSON::generate(send), headers: { 'content-type' => 'application/json'})
230
+ end
231
+
232
+ #File.unlink(File.join('data',@r.last,'callback')) rescue nil
233
+ #File.unlink(File.join('data',@r.last,'cpeeinstance.url')) rescue nil
234
+ #File.unlink(File.join('data',@r.last,'style.url')) rescue nil
235
+ #File.unlink(File.join('data',@r.last,'document.xml')) rescue nil
236
+ #File.unlink(File.join('data',@r.last,'info.json')) rescue nil
237
+
238
+ @a[0].send('reset')
239
+ nil
240
+ end
241
+ end
242
+
243
+ class GetFrames < Riddl::Implementation #{{{
244
+ def response
245
+ fname = File.join('data',@r[-2],'frames.json')
246
+ if File.exists? fname
247
+
248
+ infofile = File.join('data',@r[-2],'info.json')
249
+ infojson = JSON::parse(File.read(infofile))
250
+
251
+ #remove not used languages
252
+ file = JSON::parse(File.read(fname))
253
+
254
+ file["data"].each do |child|
255
+ child["url"] = child["url"].find{ |h| h['lang'] == infojson["lang"]}['url']
256
+ end
257
+
258
+ Riddl::Parameter::Complex.new('value','application/json',JSON.dump(file))
259
+ else
260
+ @status = 404
261
+ end
262
+ end
263
+ end #}}}
264
+
265
+ class SetDataElements < Riddl::Implementation #{{{
266
+ def response
267
+ savejson = @p.map { |o| Hash[o.name, o.value] }.to_json
268
+ path = File.join('data',@r[0],'dataelements.json')
269
+ File.write(path, savejson)
270
+
271
+ #puts xyz
272
+
273
+ #puts JSON.pretty_generate(@p.to_json)
274
+
275
+
276
+
277
+ #puts @p.length()
278
+ #puts @p[0].name
279
+ #puts @p[0].value
280
+
281
+ #fname = File.join('data',@r[-2],'dataelements.json')
282
+ #if File.exists? fname
283
+ # Riddl::Parameter::Complex.new('value','application/json',File.read(fname))
284
+ #else
285
+ # @status = 404
286
+ #end
287
+ end
288
+ end #}}}
289
+
290
+ class GetDataElements < Riddl::Implementation #{{{
291
+ def response
292
+ fname = File.join('data',@r[-2],'dataelements.json')
293
+ if File.exists? fname
294
+ Riddl::Parameter::Complex.new('value','application/json',File.read(fname))
295
+ else
296
+ @status = 404
297
+ end
298
+ end
299
+ end #}}}
300
+
301
+ class GetInfo < Riddl::Implementation #{{{
302
+ def response
303
+ fname = File.join('data',@r[-2],'info.json')
304
+ if File.exists? fname
305
+ Riddl::Parameter::Complex.new('value','application/json',File.read(fname))
306
+ else
307
+ @status = 404
308
+ end
309
+ end
310
+ end #}}}
311
+
312
+ class GetLangs < Riddl::Implementation #{{{
313
+ def response
314
+ fname = File.join('data',@r[-2],'info.json')
315
+ if File.exists? fname
316
+ infojson = JSON::parse(File.read(fname))
317
+ Riddl::Parameter::Complex.new('value','application/json',infojson["langs"])
318
+ else
319
+ @status = 404
320
+ end
321
+ end
322
+ end #}}}
323
+
324
+ class SetLang < Riddl::Implementation #{{{
325
+ def response
326
+ fname = File.join('data',@r[-2],'info.json')
327
+ if File.exists? fname
328
+ infojson = JSON::parse(File.read(fname))
329
+ infojson["lang"] = @p[0].value
330
+
331
+
332
+ #add to langs
333
+ if !infojson["langs"].include?(@p[0].value)
334
+ infojson["langs"].push(@p[0].value)
335
+ end
336
+
337
+ File.write(fname, JSON.dump(infojson))
338
+
339
+
340
+
341
+ @a[0].send('reset')
342
+ nil
343
+ else
344
+ @status = 404
345
+ end
346
+ end
347
+ end #}}}
348
+
349
+ class GetStyle < Riddl::Implementation #{{{
350
+ def response
351
+ fname = File.join('data',@r[-2],'style.url')
352
+ if File.exists? fname
353
+ Riddl::Parameter::Complex.new('url','text/plain',File.read(fname).strip)
354
+ else
355
+ @status = 404
356
+ end
357
+ end
358
+ end #}}}
359
+
360
+ class GetCpeeInstance < Riddl::Implementation #{{{
361
+ def response
362
+ fname = File.join('data',@r[-2],'cpeeinstance.url')
363
+ if File.exists? fname
364
+ Riddl::Parameter::Complex.new('url','text/plain',File.read(fname).strip)
365
+ else
366
+ @status = 404
367
+ end
368
+ end
369
+ end #}}}
370
+
371
+ class OutputTest < Riddl::Implementation #{{{
372
+ def response
373
+ puts "Test"
374
+ end
375
+ end #}}}
376
+
377
+ class Handler < Riddl::Implementation
378
+ def response
379
+ topic = @p[1].value
380
+ event_name = @p[2].value
381
+ notification = JSON.parse(@p[3].value.read)
382
+
383
+ instancenr = notification['instance']
384
+ content = notification['content']
385
+ activity = content['activity']
386
+ parameters = content['parameters']
387
+ receiving = content['received']
388
+
389
+ #puts instancenr
390
+ #puts activity
391
+ puts content['values']
392
+
393
+
394
+ if content['values']&.any?
395
+ #puts alldata['ausfuehrungen']
396
+ puts "writing file"
397
+ path = File.join('data',@r[0],'dataelements.json')
398
+ File.write(path, JSON.dump(content['values']))
399
+ end
400
+
401
+ @a[0].send(@r[0])
402
+ nil
403
+ end
404
+ end
405
+
406
+ class SSE < Riddl::SSEImplementation #{{{
407
+ def onopen
408
+ signals = @a[0]
409
+ signals.add self
410
+ send 'started'
411
+ true
412
+ end
413
+
414
+ def onclose
415
+ signals = @a[0]
416
+ signals.remove self
417
+ nil
418
+ end
419
+ end #}}}
420
+
421
+ class SSE2 < Riddl::SSEImplementation #{{{
422
+ def onopen
423
+ signals = @a[0]
424
+ signals.add self
425
+ send 'started'
426
+ true
427
+ end
428
+
429
+ def onclose
430
+ signals = @a[0]
431
+ signals.remove self
432
+ nil
433
+ end
434
+ end #}}}
435
+
436
+ class Signaling # {{{
437
+ def initialize
438
+ @binding = []
439
+ end
440
+
441
+ def add(binding)
442
+ @binding << binding
443
+ end
444
+ def remove(binding)
445
+ @binding.delete(binding)
446
+ end
447
+ def length
448
+ @binding.length
449
+ end
450
+
451
+ def send(value)
452
+ @binding.each do |b|
453
+ b.send(value)
454
+ end
455
+ end
456
+ end #}}}
457
+
458
+ def self::implementation(opts)
459
+ opts[:signals] = {}
460
+ opts[:signals2] = {}
461
+ opts[:data_dir] ||= File.expand_path(File.join(__dir__,'data'))
462
+
463
+ Proc.new do
464
+ parallel do
465
+ loop do
466
+ opts[:signals].each do |k,v|
467
+ v.send('keepalive')
468
+ end
469
+ opts[:signals2].each do |k,v|
470
+ v.send('keepalive')
471
+ end
472
+ sleep 5
473
+ end
474
+ end
475
+
476
+ on resource do
477
+ run GetTutorial if get
478
+
479
+ on resource 'getConfigs' do
480
+ run GetAllConfigs, opts[:data_dir] if get
481
+ end
482
+
483
+ on resource do |r|
484
+ idx = r[:r][0]
485
+ opts[:signals][idx] ||= Signaling.new
486
+ opts[:signals2]["handler"] ||= Signaling.new
487
+
488
+ run Get, "test" if get
489
+ run InitFrame, opts[:signals][idx] if post 'input'
490
+
491
+ run NewFrameSet, opts[:signals][idx] if put 'sframe'
492
+ run NewFrameWait, opts[:signals][idx] if put 'wframe'
493
+
494
+ run DeleteFrame, opts[:signals][idx] if post 'deleteframe'
495
+
496
+ on resource 'handler' do
497
+ run Handler, opts[:signals2]["handler"] if post
498
+ on resource 'sse' do
499
+ run SSE2, opts[:signals2]["handler"] if sse
500
+ end
501
+ end
502
+
503
+ run Delete, opts[:signals][idx] if delete 'opa'
504
+ run Delete, opts[:signals][idx] if delete 'opb'
505
+ run Delete, opts[:signals][idx] if delete 'opc'
506
+ on resource 'sse' do
507
+ run SSE, opts[:signals][idx] if sse
508
+ end
509
+ on resource 'languages' do
510
+ run GetLangs if get
511
+ run SetLang, opts[:signals][idx] if post 'lang'
512
+ end
513
+ on resource 'style.url' do
514
+ run GetStyle if get
515
+ end
516
+ on resource 'cpeeinstance.url' do
517
+ run GetCpeeInstance if get
518
+ end
519
+ on resource 'info.json' do
520
+ run GetInfo if get
521
+ end
522
+ on resource 'frames.json' do
523
+ run GetFrames if get
524
+ end
525
+ on resource 'test' do
526
+ run OutputTest if put
527
+ end
528
+
529
+ on resource 'dataelements.json' do
530
+ run SetDataElements if post
531
+ run GetDataElements if get
532
+ end
533
+ end
534
+ end
535
+ end
536
+ end
537
+
538
+ end
539
+ end
@@ -0,0 +1,60 @@
1
+ <!--
2
+ This file is part of centurio.work/out/frame.
3
+
4
+ centurio.work/out/frame is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by the Free
6
+ Software Foundation, either version 3 of the License, or (at your option) any
7
+ later version.
8
+
9
+ centurio.work/out/frame is distributed in the hope that it will be useful, but
10
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ more details.
13
+
14
+ You should have received a copy of the GNU General Public License along with
15
+ centurio.work/out/frame (file LICENSE in the main directory). If not, see
16
+ <http://www.gnu.org/licenses/>.
17
+ -->
18
+
19
+ <!DOCTYPE html>
20
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
21
+ <head>
22
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
23
+ <title>data frame</title>
24
+
25
+ <!-- libs, do not modify. When local than load local libs. -->
26
+ <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
27
+ <script type="text/javascript" src="/js_libs/jquery.browser.js"></script>
28
+ <script type="text/javascript" src="/js_libs/jquery.svg.min.js"></script>
29
+ <script type="text/javascript" src="/js_libs/jquery.svgdom.min.js"></script>
30
+ <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
31
+ <script type="text/javascript" src="/js_libs/util.js"></script>
32
+ <script type="text/javascript" src="/js_libs/printf.js"></script>
33
+ <script type="text/javascript" src="/js_libs/strftime.min.js"></script>
34
+ <script type="text/javascript" src="/js_libs/parsequery.js"></script>
35
+ <script type="text/javascript" src="/js_libs/underscore.min.js"></script>
36
+ <script type="text/javascript" src="/js_libs/jquery.caret.min.js"></script>
37
+ <script type="text/javascript" src="/js_libs/jquery.cookie.js"></script>
38
+
39
+ <!-- custom stuff, play arround -->
40
+ <script type="text/javascript" src="../js/frame_data.js"></script>
41
+ <script type="text/javascript" src="../js/language.js"></script>
42
+ <link rel="stylesheet" href="../css/frames.css" type="text/css"/>
43
+ <link class='custom' rel="stylesheet" href="" type="text/css"/>
44
+
45
+
46
+
47
+ <!-- Forms
48
+ <script src='https://centurio.work/out/forms/js/formio.full.min.js'></script>
49
+ -->
50
+ <script>
51
+ if (location.href.match(/\/$/) == null) {
52
+ location.href = location.href + '/';
53
+ }
54
+ </script>
55
+ </head>
56
+ <body is="x-ui">
57
+ Data:
58
+ <div id="alldata"></div>
59
+ </body>
60
+ </html>
@@ -0,0 +1,71 @@
1
+ <!--
2
+ This file is part of centurio.work/out/frame.
3
+
4
+ centurio.work/out/frame is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by the Free
6
+ Software Foundation, either version 3 of the License, or (at your option) any
7
+ later version.
8
+
9
+ centurio.work/out/frame is distributed in the hope that it will be useful, but
10
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
+ more details.
13
+
14
+ You should have received a copy of the GNU General Public License along with
15
+ centurio.work/out/frame (file LICENSE in the main directory). If not, see
16
+ <http://www.gnu.org/licenses/>.
17
+ -->
18
+
19
+ <!DOCTYPE html>
20
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
21
+ <head>
22
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
23
+ <title>menu frame</title>
24
+
25
+ <!-- libs, do not modify. When local than load local libs. -->
26
+ <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
27
+ <script type="text/javascript" src="/js_libs/jquery.browser.js"></script>
28
+ <script type="text/javascript" src="/js_libs/jquery.svg.min.js"></script>
29
+ <script type="text/javascript" src="/js_libs/jquery.svgdom.min.js"></script>
30
+ <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
31
+ <script type="text/javascript" src="/js_libs/util.js"></script>
32
+ <script type="text/javascript" src="/js_libs/printf.js"></script>
33
+ <script type="text/javascript" src="/js_libs/strftime.min.js"></script>
34
+ <script type="text/javascript" src="/js_libs/parsequery.js"></script>
35
+ <script type="text/javascript" src="/js_libs/underscore.min.js"></script>
36
+ <script type="text/javascript" src="/js_libs/jquery.caret.min.js"></script>
37
+ <script type="text/javascript" src="/js_libs/jquery.cookie.js"></script>
38
+
39
+ <!-- custom stuff, play arround -->
40
+ <script type="text/javascript" src="../js/test.js"></script>
41
+ <link rel="stylesheet" href="../css/design.css" type="text/css"/>
42
+ <link class='custom' rel="stylesheet" href="" type="text/css"/>
43
+ <script>
44
+ if (location.href.match(/\/$/) == null) {
45
+ location.href = location.href + '/';
46
+ }
47
+
48
+ function openlink(menuitem){
49
+ var menu = { name: menuitem };
50
+
51
+ $.ajax({
52
+ type: "PUT",
53
+ url: window.name,
54
+ contentType: "application/json",
55
+ data: JSON.stringify(menu),
56
+ success: function (data) {
57
+
58
+ }
59
+ });
60
+
61
+
62
+ //alert(xyz);
63
+ }
64
+
65
+ </script>
66
+ </head>
67
+ <body is="x-ui">
68
+ <a href="javascript:openlink('Centurio');">Centurio</a>
69
+ <a href="javascript:openlink('WAS');">WAS</a>
70
+ </body>
71
+ </html>