cpee-model-management 1.0.9 → 1.0.15

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff58402244bdf7eadbd79cebb7c4ef42f302b45354da3bc1634bd866ba273eec
4
- data.tar.gz: 3dc2729da1856011a97a42c487117fe2cc7f4e6587e6e54934559bccc68b7148
3
+ metadata.gz: ce614812f4658c4e62170443af46efcd32843661fefc6f65d22be139e16cb5e4
4
+ data.tar.gz: 2e15d839338f8be623e9b536b067778d452e68a7b3e50359672099d7db382ef7
5
5
  SHA512:
6
- metadata.gz: 130154f25420d1901fa5dd8e83f15e2eecb6609660d7fd2e30f43e202b7a1a25fbc02e408bcf0575e5d4de6dffad5cdd2561926a4824a6127b9a72c2854e0267
7
- data.tar.gz: 6be4a1c311486e3364ce6e96192ca4b654e625ae102204150b34989384ba617abe5b7ba77c40b9f59233f61dfa7185c3d88917dd685629cbd1355c2b87bc62b3
6
+ metadata.gz: 45fae847a02d31b3332ddb8394192eae4e107ec6cdbd4287f3b2408bdb46ab38e55ee27c558f7bbd04ada97db1cc74b82d3294343bb40f0b2a166a43aba47774
7
+ data.tar.gz: 67b92d5bfe550a32aab89999ef5709b4928d277d7b4ef6ca75d6cf3f032a19b266aae72004580897c85088d2e4ad4017cf2bb931b8450424b797a20d115ee4af
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cpee-model-management"
3
- s.version = "1.0.9"
3
+ s.version = "1.0.15"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0"
6
6
  s.summary = "(Lifecycle) manage your process models in a directory or git repo."
7
7
 
8
8
  s.description = "see http://cpee.org"
9
9
 
10
- s.files = Dir['{server/*,tools/**/*,lib/**/*}'] + %w(LICENSE Rakefile cpee-model-management.gemspec README.md AUTHORS)
10
+ s.files = Dir['{server/*,tools/**/*,lib/**/*,ui/**/*}'] + %w(LICENSE Rakefile cpee-model-management.gemspec README.md AUTHORS)
11
11
  s.require_path = 'lib'
12
12
  s.extra_rdoc_files = ['README.md']
13
13
  s.bindir = 'tools'
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.add_runtime_dependency 'riddl', '~> 0.99'
24
24
  s.add_runtime_dependency 'json', '~> 2.1'
25
+ s.add_runtime_dependency 'cpee', '~> 2.1', '>= 2.1.7'
25
26
  end
@@ -24,6 +24,7 @@ require 'riddl/protocols/utils'
24
24
  require 'fileutils'
25
25
  require 'pathname'
26
26
  require 'shellwords'
27
+ require 'securerandom'
27
28
 
28
29
  module CPEE
29
30
  module ModelManagement
@@ -40,9 +41,7 @@ module CPEE
40
41
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told}" "#{tnew}" 2>/dev/null`
41
42
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active'}" 2>/dev/null`
42
43
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active-uuid'}" 2>/dev/null`
43
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.author'}" "#{tnew + '.author'}" 2>/dev/null`
44
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.creator'}" "#{tnew + '.creator'}" 2>/dev/null`
45
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.stage'}" "#{tnew + '.stage'}" 2>/dev/null`
44
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.attrs'}" "#{tnew + '.author'}" 2>/dev/null`
46
45
  Dir.chdir(cdir)
47
46
  CPEE::ModelManagement::fs_mv(models,old,new) # fallback
48
47
  end
@@ -54,9 +53,7 @@ module CPEE
54
53
  FileUtils.rm_rf(tnew)
55
54
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.active" 2>/dev/null`
56
55
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.active-uuid" 2>/dev/null`
57
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.author" 2>/dev/null`
58
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.creator" 2>/dev/null`
59
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.stage" 2>/dev/null`
56
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.attrs" 2>/dev/null`
60
57
  Dir.chdir(cdir)
61
58
  CPEE::ModelManagement::fs_rm(models,new) # fallback
62
59
  end
@@ -80,9 +77,7 @@ module CPEE
80
77
  FileUtils.mv(fname,fnname) rescue nil
81
78
  File.delete(fname + '.active',fnname + '.active') rescue nil
82
79
  File.delete(fname + '.active-uuid',fnname + '.active-uuid') rescue nil
83
- FileUtils.mv(fname + '.author',fnname + '.author') rescue nil
84
- FileUtils.mv(fname + '.creator',fnname + '.creator') rescue nil
85
- FileUtils.mv(fname + '.stage',fnname + '.stage') rescue nil
80
+ FileUtils.mv(fname + '.attrs',fnname + '.attrs') rescue nil
86
81
  end
87
82
  def self::fs_cp(models,old,new)
88
83
  fname = File.join(models,old)
@@ -90,18 +85,14 @@ module CPEE
90
85
  FileUtils.cp(fname,fnname)
91
86
  File.delete(fname + '.active',fnname + '.active') rescue nil
92
87
  File.delete(fname + '.active-uuid',fnname + '.active-uuid') rescue nil
93
- FileUtils.cp(fname + '.author',fnname + '.author') rescue nil
94
- FileUtils.cp(fname + '.creator',fnname + '.creator') rescue nil
95
- FileUtils.cp(fname + '.stage',fnname + '.stage') rescue nil
88
+ FileUtils.cp(fname + '.attrs',fnname + '.attrs') rescue nil
96
89
  end
97
90
  def self::fs_rm(models,new)
98
91
  fname = File.join(models,new)
99
92
  FileUtils.rm_rf(fname)
100
93
  File.delete(fname + '.active') rescue nil
101
94
  File.delete(fname + '.active-uuid') rescue nil
102
- File.delete(fname + '.author') rescue nil
103
- File.delete(fname + '.creator') rescue nil
104
- File.delete(fname + '.stage') rescue nil
95
+ File.delete(fname + '.attrs') rescue nil
105
96
  end
106
97
  def self::fs_shift(models,new)
107
98
  fname = File.join(models,new)
@@ -168,14 +159,16 @@ module CPEE
168
159
  if op == 'delete'
169
160
  { :op => op, :type => :dir, :name => File.basename(f) }
170
161
  else
171
- { :op => op, :type => :dir, :name => File.basename(f), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
162
+ attrs = JSON::load File.open(f + '.attrs')
163
+ { :op => op, :type => :dir, :name => File.basename(f), :creator => attrs['creator'], :date => File.mtime(f).xmlschema }
172
164
  end
173
165
  else
174
166
  if op == 'delete'
175
167
  { :op => op, :type => :file, :name => f.sub(Regexp.compile(File.join(models,'/')),'') }
176
168
  else
177
- fstage = File.read(f + '.stage').strip rescue 'draft'
178
- { :op => op, :type => :file, :name => f.sub(Regexp.compile(File.join(models,'/')),''), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema }
169
+ attrs = JSON::load File.open(f + '.attrs')
170
+ fstage = attrs['design_stage'] rescue 'draft'
171
+ { :op => op, :type => :file, :name => f.sub(Regexp.compile(File.join(models,'/')),''), :creator => attrs['creator'], :author => attrs['author'], :stage => fstage, :date => File.mtime(f).xmlschema }
179
172
  end
180
173
  end
181
174
  what[:source] = s.sub(/models\//,'') unless s.nil?
@@ -192,12 +185,13 @@ module CPEE
192
185
  stage = [@p[0]&.value] || ['draft']
193
186
  stage << views[stage[0]] if views && views[stage[0]]
194
187
 
195
-
196
188
  names = Dir.glob(File.join(models,where,'*.dir')).map do |f|
197
- { :type => :dir, :name => File.basename(f), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
189
+ attrs = JSON::load File.open(f + '.attrs')
190
+ { :type => :dir, :name => File.basename(f), :creator => attrs['creator'], :date => File.mtime(f).xmlschema }
198
191
  end.compact.uniq.sort_by{ |e| e[:name] } + Dir.glob(File.join(models,where,'*.xml')).map do |f|
199
- fstage = File.read(f + '.stage').strip rescue 'draft'
200
- { :type => :file, :name => File.basename(f), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
192
+ attrs = JSON::load File.open(f + '.attrs')
193
+ fstage = attrs['design_stage'] rescue 'draft'
194
+ { :type => :file, :name => File.basename(f), :creator => attrs['creator'], :author => attrs['author'], :guarded => attrs['resource_restriction'], :guarded_what => attrs['resource_id'], :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
201
195
  end.compact.uniq.sort_by{ |e| e[:name] }
202
196
 
203
197
  Riddl::Parameter::Complex.new('list','application/json',JSON::pretty_generate(names))
@@ -211,10 +205,12 @@ module CPEE
211
205
  stage << views[stage[0]] if views && views[stage[0]]
212
206
 
213
207
  names = Dir.glob(File.join(models,'*.dir/*.xml')).map do |f|
214
- { :type => :file, :name => File.join(File.basename(File.dirname(f)),File.basename(f)), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
208
+ attrs = JSON::load File.open(f + '.attrs')
209
+ { :type => :file, :name => File.join(File.basename(File.dirname(f)),File.basename(f)), :creator => attrs['creator'], :date => File.mtime(f).xmlschema }
215
210
  end.compact.uniq.sort_by{ |e| e[:name] } + Dir.glob(File.join(models,'*.xml')).map do |f|
216
- fstage = File.read(f + '.stage').strip rescue 'draft'
217
- { :type => :file, :name => File.basename(f), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
211
+ attrs = JSON::load File.open(f + '.attrs')
212
+ fstage = attrs['design_stage'] rescue 'draft'
213
+ { :type => :file, :name => File.basename(f), :creator => attrs['creator'], :author => attrs['author'], :guarded => attrs['resource_restriction'], :guarded_what => attrs['resource_id'], :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
218
214
  end.compact.uniq.sort_by{ |e| e[:name] }
219
215
 
220
216
  Riddl::Parameter::Complex.new('list','application/json',JSON::pretty_generate(names))
@@ -240,6 +236,7 @@ module CPEE
240
236
  dn = CPEE::ModelManagement::get_dn @h['DN']
241
237
  author = dn['GN'] + ' ' + dn['SN']
242
238
 
239
+ attrs = {}
243
240
  XML::Smart::modify(fname) do |doc|
244
241
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
245
242
  doc.find('/p:testset/p:attributes/p:author').each do |ele|
@@ -251,9 +248,11 @@ module CPEE
251
248
  doc.find('/p:testset/p:attributes/p:theme').each do |ele|
252
249
  ele.text = themes[nstage] || 'model'
253
250
  end
251
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
252
+ [e.qname.name,e.text]
253
+ end.to_h
254
254
  end
255
- File.write(fname + '.author',author)
256
- File.write(fname + '.stage',nstage)
255
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
257
256
 
258
257
  CPEE::ModelManagement::op author, 'shift', models, File.join('.', where, name + '.xml'), File.join('.', where, name + '.xml')
259
258
  CPEE::ModelManagement::notify conns, 'shift', models, fname, fname
@@ -280,6 +279,7 @@ module CPEE
280
279
  dn = CPEE::ModelManagement::get_dn @h['DN']
281
280
  author = dn['GN'] + ' ' + dn['SN']
282
281
 
282
+ attrs = {}
283
283
  XML::Smart::modify(fname) do |doc|
284
284
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
285
285
  doc.find('/p:testset/p:attributes/p:info').each do |ele|
@@ -288,8 +288,11 @@ module CPEE
288
288
  doc.find('/p:testset/p:attributes/p:author').each do |ele|
289
289
  ele.text = author
290
290
  end
291
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
292
+ [e.qname.name,e.text]
293
+ end.to_h
291
294
  end
292
- File.write(fname + '.author',author)
295
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
293
296
 
294
297
  CPEE::ModelManagement::op author, 'mv', models, File.join('.', where, nname + '.xml'), File.join('.', where, name + '.xml')
295
298
  CPEE::ModelManagement::notify conns, 'rename', models, fnname, fname
@@ -312,7 +315,10 @@ module CPEE
312
315
 
313
316
  dn = CPEE::ModelManagement::get_dn @h['DN']
314
317
  author = dn['GN'] + ' ' + dn['SN']
315
- File.write(fname + '.author',author)
318
+
319
+ attrs = JSON::load File.open(fname + '.attrs')
320
+ attrs['author'] = author
321
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
316
322
 
317
323
  CPEE::ModelManagement::op author, 'mv', models, File.join(nname + '.dir'), File.join(name + '.dir')
318
324
  CPEE::ModelManagement::notify conns, 'rename', models, fnname, fname
@@ -338,8 +344,11 @@ module CPEE
338
344
 
339
345
  Dir.mkdir(fname)
340
346
  FileUtils.touch(File.join(fname,'.gitignore'))
341
- File.write(fname + '.creator',creator)
342
- File.write(fname + '.author',creator)
347
+
348
+ attrs = JSON::load File.open(fname + '.attrs')
349
+ attrs['creator'] = creator
350
+ attrs['author'] = creator
351
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
343
352
 
344
353
  CPEE::ModelManagement::op creator, 'add', models, name + '.dir'
345
354
  CPEE::ModelManagement::notify conns, 'create', models, fname
@@ -363,7 +372,8 @@ module CPEE
363
372
  source = @p[1] ? File.join(models,where,@p[1].value) : (templates[stage] ? templates[stage] : 'testset.xml')
364
373
  fname = File.join(models,where,name + '.xml')
365
374
 
366
- stage = File.read(source + '.stage') if stage.nil? && File.exists?(source + '.stage')
375
+ attrs = JSON::load File.open(fname + '.attrs')
376
+ stage = attrs['design_stage'] if stage.nil? && attrs['design_stage']
367
377
  stage = views[stage] if views && views[stage]
368
378
 
369
379
  counter = 0
@@ -375,6 +385,7 @@ module CPEE
375
385
  dn = CPEE::ModelManagement::get_dn @h['DN']
376
386
  creator = dn['GN'] + ' ' + dn['SN']
377
387
  FileUtils.cp(source,fname)
388
+ attrs = {}
378
389
  XML::Smart::modify(fname) do |doc|
379
390
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
380
391
  doc.find('/p:testset/p:attributes/p:info').each do |ele|
@@ -389,15 +400,19 @@ module CPEE
389
400
  doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
390
401
  ele.text = where
391
402
  end
403
+ doc.find('/p:testset/p:attributes/p:model_uuid').each do |ele|
404
+ ele.text = SecureRandom.uuid
405
+ end
392
406
  if stage
393
407
  doc.find('/p:testset/p:attributes/p:design_stage').each do |ele|
394
408
  ele.text = stage
395
409
  end
396
410
  end
411
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
412
+ [e.qname.name,e.text]
413
+ end.to_h
397
414
  end
398
- File.write(fname + '.creator',creator)
399
- File.write(fname + '.author',creator)
400
- File.write(fname + '.stage',stage)
415
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
401
416
 
402
417
  CPEE::ModelManagement::op creator, 'add', models, File.join('.', where, name + '.xml')
403
418
  CPEE::ModelManagement::notify conns, 'create', models, fname
@@ -492,13 +507,17 @@ module CPEE
492
507
  dn = CPEE::ModelManagement::get_dn @h['DN']
493
508
  author = dn['GN'] + ' ' + dn['SN']
494
509
  if !File.exist?(File.join(models,to,name + '.xml'))
510
+ attrs = {}
495
511
  XML::Smart::modify(fname) do |doc|
496
512
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
497
513
  doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
498
514
  ele.text = to
499
515
  end
516
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
517
+ [e.qname.name,e.text]
518
+ end.to_h
500
519
  end
501
- File.write(fname + '.author',author)
520
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
502
521
 
503
522
  CPEE::ModelManagement::op author, 'mv', models, File.join('.', to, name + '.xml'), File.join('.', where, name + '.xml')
504
523
  CPEE::ModelManagement::notify conns, 'move', models, File.join(models,to,name + '.xml'), fname
@@ -518,20 +537,25 @@ module CPEE
518
537
 
519
538
  if File.exists?(fname)
520
539
  author = dn['GN'] + ' ' + dn['SN']
540
+ attrs = {}
521
541
  XML::Smart.string(cont) do |doc|
522
542
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
523
- unless File.exists?(File.join(models,where,name + '.xml.creator'))
524
- doc.find('/p:testset/p:attributes/p:author').each do |ele|
525
- File.write(File.join(models,where,name + '.xml.creator'),ele.text)
526
- end
527
- end
528
543
  doc.find('/p:testset/p:attributes/p:author').each do |ele|
529
544
  ele.text = dn['GN'] + ' ' + dn['SN']
530
545
  end
546
+ if doc.find('/p:testset/p:attributes/p:design_stage').empty?
547
+ doc.find('/p:testset/p:attributes').first.add('p:design_stage','draft')
548
+ else
549
+ doc.find('/p:testset/p:attributes/p:design_stage').each do |ele|
550
+ ele.text = 'draft' if ele.text.strip == ''
551
+ end
552
+ end
553
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
554
+ [e.qname.name,e.text]
555
+ end.to_h
531
556
  File.write(fname,doc.to_s)
532
- File.write(fname + '.author',author)
533
- File.write(fname + '.stage',doc.find('string(/p:testset/p:attributes/p:design_stage)').sub(/^$/,'draft'))
534
557
  end
558
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
535
559
  CPEE::ModelManagement::op author, 'add', models, File.join('.', where, name + '.xml')
536
560
  CPEE::ModelManagement::notify conns, 'put', models, fname
537
561
  else
data/server/model.xml CHANGED
@@ -25,6 +25,10 @@
25
25
  <info>none</info>
26
26
  <creator>Juergen Mangler</creator>
27
27
  <author>Juergen Mangler</author>
28
+ <resource_restriction>none</resource_restriction>
29
+ <resource_id></resource_id>
30
+ <model_uuid></model_uuid>
31
+ <model_version></model_version>
28
32
  <modeltype>CPEE</modeltype>
29
33
  <theme>model</theme>
30
34
  <design_dir></design_dir>
data/server/moma.conf CHANGED
@@ -1,5 +1,6 @@
1
1
  :port: 9316
2
2
  :models: models
3
+ :location: https://cpee.org/design/server/
3
4
  :instantiate: https://cpee.org/flow/start/
4
5
  :cockpit:
5
6
  draft: https://cpee.org/flow/model.html?monitor=
data/server/testset.xml CHANGED
@@ -18,6 +18,10 @@
18
18
  <creator>Juergen Mangler</creator>
19
19
  <author>Juergen Mangler</author>
20
20
  <modeltype>CPEE</modeltype>
21
+ <resource_restriction>none</resource_restriction>
22
+ <resource_id></resource_id>
23
+ <model_uuid></model_uuid>
24
+ <model_version></model_version>
21
25
  <theme>extended</theme>
22
26
  <design_dir></design_dir>
23
27
  <design_stage>draft</design_stage>
data/tools/cpee-moma CHANGED
@@ -5,6 +5,9 @@ require 'optparse'
5
5
  require 'fileutils'
6
6
  require 'xml/smart'
7
7
  require 'zip'
8
+ require 'typhoeus'
9
+ require 'json'
10
+ require 'securerandom'
8
11
 
9
12
  def wrap(s, width=78, indent=18)
10
13
  lines = []
@@ -24,6 +27,29 @@ def wrap(s, width=78, indent=18)
24
27
  return lines.join "\n"
25
28
  end
26
29
 
30
+ def js_libs(cockpit)
31
+ res = Typhoeus.get('https://cpee.org/js_libs/js_libs.zip')
32
+ if res.success?
33
+ File.write(File.join(cockpit,'js_libs.zip'),res.response_body)
34
+ Zip::File.open(File.join(cockpit,'js_libs.zip')) do |zip_file|
35
+ zip_file.each do |entry|
36
+ case entry.ftype
37
+ when :directory
38
+ Dir.mkdir(File.join(cockpit,entry.name)) rescue nil
39
+ when :file
40
+ File.write(File.join(cockpit,entry.name),entry.get_input_stream.read)
41
+ when :symlink
42
+ FileUtils.ln_s(File.join('.',entry.get_input_stream.read),File.join(cockpit,entry.name), force: true)
43
+ end
44
+ end
45
+ end
46
+ true
47
+ else
48
+ puts 'Internet access required to download javascript libs from "http://cpee.org/js_libs/js_libs.zip".'
49
+ false
50
+ end
51
+ end
52
+
27
53
  ARGV.options { |opt|
28
54
  opt.summary_indent = ' ' * 2
29
55
  opt.summary_width = 15
@@ -60,12 +86,29 @@ if command == 'cpui'
60
86
  js_libs(p1)
61
87
  elsif command == 'convert'
62
88
  Dir['*.xml'].each do |f|
63
- XML::Smart.modify(f) do |doc|
89
+ XML::Smart.open(f) do |doc|
64
90
  doc.register_namespace 'x', 'http://cpee.org/ns/properties/2.0'
65
91
  if doc.root.qname.name == 'testset'
66
92
  name = File.basename(f,'.xml')
67
93
  creator = author = design_dir = design_stage = nil
68
94
 
95
+ if doc.find('/x:testset/x:attributes').length == 0
96
+ n = doc.root.add('x:attributes')
97
+ end
98
+
99
+ if doc.find('/x:testset/x:attributes/x:model_uuid').length == 0
100
+ n = doc.find('/x:testset/x:attributes').first
101
+ n.add('x:model_uuid',SecureRandom.uuid)
102
+ end
103
+ if doc.find('/x:testset/x:attributes/x:theme').length == 0
104
+ n = doc.find('/x:testset/x:attributes').first
105
+ n.add('x:theme','extended')
106
+ end
107
+ if doc.find('/x:testset/x:attributes/x:info').length == 0
108
+ n = doc.find('/x:testset/x:attributes').first
109
+ n.add('x:info',name)
110
+ end
111
+
69
112
  if (dt = doc.find('/x:testset/x:attributes/x:creator')).length > 0
70
113
  dt.each do |e|
71
114
  creator = e.text
@@ -76,7 +119,6 @@ elsif command == 'convert'
76
119
  e.add('x:creator',creator)
77
120
  end
78
121
  end
79
- File.write(f + '.creator',creator)
80
122
 
81
123
  if (dt = doc.find('/x:testset/x:attributes/x:author')).length > 0
82
124
  dt.each do |e|
@@ -88,7 +130,6 @@ elsif command == 'convert'
88
130
  e.add('x:author',author)
89
131
  end
90
132
  end
91
- File.write(f + '.author',author)
92
133
 
93
134
  if (dt = doc.find('/x:testset/x:attributes/x:design_stage')).length > 0
94
135
  dt.each do |e|
@@ -100,14 +141,15 @@ elsif command == 'convert'
100
141
  e.add('x:design_stage',design_stage)
101
142
  end
102
143
  end
103
- File.write(f + '.stage',design_stage)
104
144
 
145
+ dd = ENV['PWD'] || Dir.pwd
146
+ ma = dd.scan(/\/([^\/]+\.dir)/)
147
+ design_dir = ma.join('/')
105
148
  if (dt = doc.find('/x:testset/x:attributes/x:design_dir')).length > 0
106
149
  dt.each do |e|
107
- design_dir = e.text
150
+ e.text = design_dir
108
151
  end
109
152
  else
110
- design_dir = Dir.pwd.sub(/^.*?models\/?/,'')
111
153
  doc.find('/x:testset/x:attributes').each do |e|
112
154
  e.add('x:design_dir',design_dir)
113
155
  end
@@ -118,9 +160,28 @@ elsif command == 'convert'
118
160
  e.text = name
119
161
  end
120
162
  end
163
+
164
+
165
+ attrs = doc.find('/x:testset/x:attributes/*').map do |e|
166
+ [e.qname.name,e.text]
167
+ end.to_h
168
+ File.write(f + '.attrs',JSON::pretty_generate(attrs))
169
+
170
+ File.unlink(f + '.creator') rescue nil
171
+ File.unlink(f + '.author') rescue nil
172
+ File.unlink(f + '.stage') rescue nil
121
173
  end
122
174
  end
123
175
  end
176
+ Dir['*.dir'].each do |f|
177
+ attrs = JSON::load File.open(f + '.attrs') rescue {}
178
+ attrs['creator'] = File.read(f + '.creator') if File.exists?(f + '.creator')
179
+ attrs['author'] = File.read(f + '.author') if File.exists?(f + '.author')
180
+ File.write(f + '.attrs',JSON::pretty_generate(attrs))
181
+
182
+ File.unlink(f + '.creator') rescue nil
183
+ File.unlink(f + '.author') rescue nil
184
+ end
124
185
  elsif command == 'new'
125
186
  if !File.exists?(p1)
126
187
  FileUtils.mkdir(File.join(p1)) rescue nil
data/ui/css/design.css ADDED
@@ -0,0 +1,62 @@
1
+ td {
2
+ padding-right: 1em;
3
+ }
4
+
5
+ td[data-class=model] {
6
+ font-size: 1.7em;
7
+ }
8
+ td[data-class=folder] {
9
+ font-size: 1.7em;
10
+ }
11
+ td[data-class=ops] {
12
+ cursor: pointer;
13
+ }
14
+
15
+ td[draggable] {
16
+ cursor: move;
17
+ }
18
+
19
+ form input {
20
+ width: 45em !important;
21
+ }
22
+
23
+ ui-behind {
24
+ text-transform: capitalize;
25
+ font-weight: bold;
26
+ color: #d0d0d0;
27
+ }
28
+
29
+ ui-behind span {
30
+ cursor: pointer;
31
+ }
32
+
33
+ [is="x-ui-"] table.ui-table {
34
+ border-collapse: collapse;
35
+ }
36
+ [is="x-ui-"] table.ui-table thead th {
37
+ font-weight: bold;
38
+ text-align: left;
39
+ padding: 0.3em 0.5em;
40
+ }
41
+ [is="x-ui-"] table.ui-table tbody td {
42
+ padding: 0.1em 0.5em;
43
+ }
44
+ [is="x-ui-"] table.ui-table tbody tr:nth-child(odd) td {
45
+ background-color: var(--x-ui-content-light-background);
46
+ }
47
+ [is="x-ui-"] table.ui-table tbody tr:hover td {
48
+ background-color: var(--x-ui-content-hover-background);
49
+ }
50
+
51
+ [is="x-ui-"] table.ui-table tbody tr:nth-child(odd) td[data-class=ops] {
52
+ background-color: #d0d0d0;
53
+ }
54
+ [is="x-ui-"] table.ui-table tbody tr:hover td[data-class=ops] {
55
+ background-color: #99cee6b0;
56
+ }
57
+
58
+ [is="x-ui-"] ui-rest > ui-content > ui-area { padding: 1em; }
59
+
60
+ tr.contextmenuitem .capitalized {
61
+ text-transform: capitalize;
62
+ }
data/ui/index.html ADDED
@@ -0,0 +1,168 @@
1
+ <!--
2
+ This file is part of CPEE-MODEL-MANAGEMENT.
3
+
4
+ CPEE-MODEL-MANAGEMENT is free software: you can redistribute it and/or
5
+ modify it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or (at your
7
+ option) any later version.
8
+
9
+ CPEE-MODEL-MANAGEMENT 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
+ CPEE-MODEL-MANAGEMENT (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="en" xml:lang="en">
21
+ <head>
22
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
23
+ <title>Design</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
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
40
+
41
+ <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
42
+
43
+ <script type="text/javascript" src="/js_libs/uidash.js"></script>
44
+ <script type="text/javascript" src="/js_libs/custommenu.js"></script>
45
+
46
+ <link rel="stylesheet" href="/js_libs/custommenu.css" type="text/css"/>
47
+ <link rel="stylesheet" href="/js_libs/uidash.css" type="text/css"/>
48
+
49
+ <link rel="stylesheet" href="/global_ui/ui.css" type="text/css"/>
50
+
51
+ <link rel="stylesheet" href="/js_libs/relaxngui.css" type="text/css"/>
52
+
53
+ <!-- custom stuff, play arround -->
54
+ <link rel="stylesheet" href="css/design.css" type="text/css"/>
55
+ <script type="text/javascript" src="js/design.js"></script>
56
+ </head>
57
+ <body is="x-ui-">
58
+ <ui-rest id="main">
59
+ <ui-tabbar>
60
+ <ui-before ></ui-before>
61
+ <ui-tab class="" data-tab="models" >Models</ui-tab>
62
+ <ui-tab class="inactive" data-tab="newmodel">New Model</ui-tab>
63
+ <ui-tab class="inactive" data-tab="newdir" >New Dir</ui-tab>
64
+ <ui-space ></ui-space>
65
+ <ui-tab class="inactive" data-tab="running" >Running</ui-tab>
66
+ <ui-tab class="inactive" data-tab="stopped" >Stopped</ui-tab>
67
+ <ui-behind ><span></span></ui-behind>
68
+ <ui-last ><a class="logo" href=".."></a></ui-last>
69
+ </ui-tabbar>
70
+ <ui-content class="noselect">
71
+ <ui-area data-belongs-to-tab="models">
72
+ <p>Your Models are saved/versioned in <a target='_blank' href='https://git-scm.com/'>GIT</a>. So fret not. Just send an email to <a href="mail:helpdesk@acdp.at">helpdesk@acdp.at</a> if you are lost. And as always: <a target='_blank' href='https://www.youtube.com/watch?v=kkxj5xVLyj0&feature=youtu.be&t=56'>get dressed for success</a>.</p>
73
+ <table id="models" class='ui-table'>
74
+ <thead>
75
+ <th></th>
76
+ <th>Name</th>
77
+ <th><abbr title='force new instance'>F</abbr></th>
78
+ <th><abbr title='link to model source'>M</abbr></th>
79
+ <th>Changed By</th>
80
+ <th><abbr title='Guarded'>G</abbr></th>
81
+ <th><abbr title='Resource'>R</abbr></th>
82
+ <th>Changed At</th>
83
+ <th><abbr title='Operations'>Op</abbr></th>
84
+ </thead>
85
+ <template id="up">
86
+ <tr>
87
+ <td data-class='folder' class="noselect">📁</td>
88
+ <td data-class='name' data-full-name=''><a href=''></a></td>
89
+ <td></td>
90
+ <td></td>
91
+ <td></td>
92
+ <td></td>
93
+ <td></td>
94
+ <td data-class='date'></td>
95
+ <td data-class=''></td>
96
+ </tr>
97
+ </template>
98
+ <template id="folder">
99
+ <tr>
100
+ <td data-class='folder' class="noselect">📁</td>
101
+ <td data-class='name' data-full-name=''><a href=''></a></td>
102
+ <td></td>
103
+ <td></td>
104
+ <td></td>
105
+ <td></td>
106
+ <td></td>
107
+ <td data-class='date'></td>
108
+ <td data-class='ops' class="noselect"><span>…</span></td>
109
+ </tr>
110
+ </template>
111
+ <template id="model">
112
+ <tr>
113
+ <td data-class='model' class="noselect" draggable="true" title='drag to folders to move'>𝌭</td>
114
+ <td data-class='name' data-full-name=''><a target='_blank' href=''></a></td>
115
+ <td data-class='force'>[<a target='_blank' href='' title='force new instance'>F</a>]</td>
116
+ <td data-class='raw'>[<a target='_blank' href='' title='link to model source'>M</a>]</td>
117
+ <td data-class='author'></td>
118
+ <td data-class='guarded'><abbr title=''></abbr></td>
119
+ <td data-class='resource'></td>
120
+ <td data-class='date'></td>
121
+ <td data-class='ops' class="noselect"><span>…</span></td>
122
+ </tr>
123
+ </template>
124
+ <tbody>
125
+ </tbody>
126
+ </table>
127
+ </ui-area>
128
+ <ui-area data-belongs-to-tab="newmodel" class="inactive">
129
+ <p>
130
+ Create an empty model. Beware, if a model of the same name already
131
+ exists in one of the categories (e.g. draft, development,
132
+ production, archive) it can not be created. To protect you from
133
+ getting confused and shooting yourself in the foot in your little
134
+ modelling world we allow only unique names. Better safe than sorry.
135
+ </p>
136
+ <form id="newmod">
137
+ <input type="hidden" name="stage" value=""/>
138
+ <input type="hidden" name="dir" value=""/>
139
+ <p>
140
+ <input type="text" name="new" required pattern="^[a-zA-Z0-9öäüÖÄÜ _-]+" placeholder="Filename (no extension necessary). Only use characters, spaces, underlines and dashes."/>
141
+ </p>
142
+ <p>
143
+ <button>New Model</button>
144
+ </p>
145
+ </form>
146
+ </ui-area>
147
+ <ui-area data-belongs-to-tab="newdir" class="inactive">
148
+ <p>
149
+ Create an empty directory. Beware, if a directory of the same name
150
+ already exists in one of the categories (e.g. draft, development,
151
+ production, archive) it can not be created. To protect you from
152
+ getting confused and shooting yourself in the foot in your little
153
+ modelling world we allow only unique names. Better safe than sorry.
154
+ </p>
155
+ <form id="newdir">
156
+ <input type="hidden" name="stage" value=""/>
157
+ <p>
158
+ <input type="text" name="newdir" required pattern="^[a-zA-Z0-9öäüÖÄÜ _-]+" placeholder="Directory name. Only use characters, spaces, underlines and dashes."/>
159
+ </p>
160
+ <p>
161
+ <button>New Directory</button>
162
+ </p>
163
+ </id>
164
+ </ui-area>
165
+ </ui-content>
166
+ </ui-rest>
167
+ </body>
168
+ </html>
data/ui/js/design.js ADDED
@@ -0,0 +1,240 @@
1
+ var gstage;
2
+ var gdir;
3
+
4
+ function move_it(name,todir) {
5
+ $.ajax({
6
+ type: "PUT",
7
+ url: "server/" + gdir + name,
8
+ data: { dir: todir }
9
+ });
10
+ }
11
+ function shift_it(name,to) {
12
+ $.ajax({
13
+ type: "PUT",
14
+ url: "server/" + gdir + name,
15
+ data: { stage: to }
16
+ });
17
+ }
18
+ function rename_it(name) {
19
+ var newname;
20
+ if (newname = prompt('New name please!',name.replace(/\.xml$/,'').replace(/\.dir$/,''))) {
21
+ $.ajax({
22
+ type: "PUT",
23
+ url: "server/" + gdir + name,
24
+ data: { new: newname }
25
+ });
26
+ }
27
+ }
28
+ function duplicate_it(name) {
29
+ var newname;
30
+ if (newname = prompt('New name please!',name.replace(/\.xml$/,'').replace(/\.dir$/,''))) {
31
+ $.ajax({
32
+ type: "POST",
33
+ url: "server/" + gdir,
34
+ data: { new: newname, old: name }
35
+ });
36
+ }
37
+ }
38
+ function delete_it(name) {
39
+ if (confirm('Are you really, really, REALLY sure!')) {
40
+ $.ajax({
41
+ type: "DELETE",
42
+ url: "server/" + gdir + name
43
+ });
44
+ }
45
+ }
46
+
47
+ function es_init(gdir,gstage) {
48
+ var es = new EventSource('server/');
49
+ es.onopen = function() {
50
+ console.log('es open');
51
+ };
52
+ es.onmessage = function(e) {
53
+ paint(gdir,gstage);
54
+ };
55
+ es.onerror = function() {
56
+ console.log('es error');
57
+ // es_init();
58
+ };
59
+ }
60
+
61
+ function paint(gdir,gstage) {
62
+ $('#models tbody').empty();
63
+ if (gdir && gdir != '') {
64
+ var clone = document.importNode(document.querySelector('#up').content,true);
65
+ $('[data-class=name] a',clone).text('..');
66
+ $('[data-class=name] a',clone).attr('href',window.location.pathname + '?stage=' + gstage + '&dir=');
67
+ $('#models tbody').append(clone);
68
+ }
69
+ $.ajax({
70
+ type: "GET",
71
+ url: "server/" + gdir,
72
+ data: { stage: gstage },
73
+ success: function(res) {
74
+ $(res).each(function(k,data) {
75
+ if (data.type == 'dir') {
76
+ var clone = document.importNode(document.querySelector('#folder').content,true);
77
+ $('[data-class=name] a',clone).text(data['name'].replace(/\.dir$/,''));
78
+ $('[data-class=name]',clone).attr('data-full-name',data['name']);
79
+ $('[data-class=name] a',clone).attr('href',window.location.pathname + '?stage=' + gstage + '&dir=' + data['name']);
80
+ } else {
81
+ var clone = document.importNode(document.querySelector('#model').content,true);
82
+ $('[data-class=name] a',clone).text(data['name']);
83
+ $('[data-class=name]',clone).attr('data-full-name',data['name']);
84
+ $('[data-class=name] a',clone).attr('href','server/' + gdir + data['name'] + '/open?stage=' + gstage);
85
+ $('[data-class=force] a',clone).attr('href','server/' + gdir + data['name'] + '/open-new?stage=' + gstage);
86
+ $('[data-class=raw] a',clone).attr('href','server/' + gdir + data['name']);
87
+
88
+ console.log(data);
89
+ $('[data-class=guarded] abbr',clone).attr('title',data['guarded']);
90
+ $('[data-class=guarded] abbr',clone).text(data['guarded'].match(/none/i) ? '' : data['guarded'].charAt(0).toUpperCase());
91
+ $('[data-class=resource]',clone).text(data['guarded_what']);
92
+ }
93
+ $('[data-class=author]',clone).text(data['author']);
94
+ $('[data-class=date]',clone).text(new Date(data['date']).strftime('%Y-%m-%d, %H:%M:%S'));
95
+ $('#models tbody').append(clone);
96
+ });
97
+ }
98
+ });
99
+ }
100
+
101
+ function change_it(gdir,gstage) {
102
+ window.location.href = window.location.pathname + '?stage=' + gstage + '&dir=' + gdir;
103
+ }
104
+
105
+ $(document).ready(function() {
106
+ const queryString = window.location.search;
107
+ const urlParams = new URLSearchParams(queryString);
108
+
109
+ gstage = urlParams.get('stage') || 'draft';
110
+ gdir = urlParams.get('dir') ? (urlParams.get('dir') + '/').replace(/\/+/,'/') : '';
111
+
112
+ es_init(gdir,gstage);
113
+
114
+ var shifts = []
115
+ $.ajax({
116
+ type: "GET",
117
+ url: "server/",
118
+ data: { stages: 'stages' },
119
+ success: (r) => {
120
+ shifts = shifts.concat(r);
121
+ shifts = shifts.filter(item => item !== gstage);
122
+ }
123
+ });
124
+
125
+ $('input[name=stage]').val(gstage);
126
+ $('input[name=dir]').val(gdir);
127
+ $('ui-behind span').text(gstage);
128
+ $('ui-behind span').click((e) => {
129
+ if (shifts.length > 0) {
130
+ var menu = {};
131
+ menu['Change to'] = [];
132
+ shifts.forEach(ele => {
133
+ menu['Change to'].push(
134
+ {
135
+ 'label': ele,
136
+ 'function_call': change_it,
137
+ 'text_icon': '➔',
138
+ 'type': undefined,
139
+ 'class': 'capitalized',
140
+ 'params': [gdir,ele]
141
+ }
142
+ );
143
+ });
144
+ new CustomMenu(e).contextmenu(menu);
145
+ }
146
+ });
147
+
148
+ var dragged;
149
+ $('#models').on('drag','td[data-class=model]',false);
150
+ $('#models').on('dragstart','td[data-class=model]',(e) => {
151
+ dragged = $(e.currentTarget).parents('tr').find('td[data-class=name]').text();
152
+ });
153
+ $('#models').on('dragover','td[data-class=folder]',false);
154
+ $('#models').on('drop','td[data-class=folder]',(e) => {
155
+ e.preventDefault();
156
+ e.stopPropagation();
157
+ if (dragged) {
158
+ var todir = $(e.currentTarget).parents('tr').find('td[data-class=name]').text();
159
+ todir = todir.replace(/\./g,'');
160
+ if (todir != '') {
161
+ todir += '.dir';
162
+ }
163
+ move_it(dragged,todir);
164
+ dragged = undefined;
165
+ }
166
+ });
167
+ $('#models').on('click','td[data-class=ops]',(e) => {
168
+ var menu = {};
169
+ var name = $(e.currentTarget).parents('tr').find('td[data-class=name]').attr('data-full-name');
170
+ menu['Operations'] = [
171
+ {
172
+ 'label': 'Delete',
173
+ 'function_call': delete_it,
174
+ 'text_icon': '❌',
175
+ 'type': undefined,
176
+ 'params': [name]
177
+ },
178
+ {
179
+ 'label': 'Rename',
180
+ 'function_call': rename_it,
181
+ 'type': undefined,
182
+ 'text_icon': '📛',
183
+ 'params': [name]
184
+ }
185
+ ];
186
+ if (name.match(/\.xml$/)) {
187
+ menu['Operations'].unshift(
188
+ {
189
+ 'label': 'Duplicate',
190
+ 'function_call': duplicate_it,
191
+ 'text_icon': '➕',
192
+ 'type': undefined,
193
+ 'params': [name]
194
+ }
195
+ );
196
+ }
197
+ if (shifts.length > 0) {
198
+ menu['Shifting'] = [];
199
+ shifts.forEach(ele => {
200
+ menu['Shifting'].push(
201
+ {
202
+ 'label': 'Shift to ' + ele,
203
+ 'function_call': shift_it,
204
+ 'text_icon': '➔',
205
+ 'type': undefined,
206
+ 'params': [name,ele]
207
+ }
208
+ );
209
+ });
210
+ }
211
+ new CustomMenu(e).contextmenu(menu);
212
+ });
213
+
214
+ history.pushState({}, document.title, window.location.pathname + '?stage=' + gstage + '&dir=' + gdir);
215
+ paint(gdir,gstage);
216
+
217
+ $('#newmod').on('submit',(e) => {
218
+ $.ajax({
219
+ type: "POST",
220
+ url: "server/" + gdir,
221
+ data: { stage: gstage, new: $("#newmod input[name=new]").val() },
222
+ success: (r) => {
223
+ uidash_activate_tab($('ui-tab').first());
224
+ }
225
+ });
226
+ return false;
227
+ });
228
+
229
+ $('#newdir').on('submit',(e) => {
230
+ $.ajax({
231
+ type: "POST",
232
+ url: "server/",
233
+ data: { dir: $("#newdir input[name=newdir]").val() },
234
+ success: (r) => {
235
+ uidash_activate_tab($('ui-tab').first());
236
+ }
237
+ });
238
+ return false;
239
+ });
240
+ });
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpee-model-management
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.9
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juergen eTM Mangler
8
8
  autorequire:
9
9
  bindir: tools
10
10
  cert_chain: []
11
- date: 2021-05-19 00:00:00.000000000 Z
11
+ date: 2021-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: riddl
@@ -38,6 +38,26 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cpee
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.1'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 2.1.7
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '2.1'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 2.1.7
41
61
  description: see http://cpee.org
42
62
  email: juergen.mangler@gmail.com
43
63
  executables:
@@ -60,6 +80,9 @@ files:
60
80
  - server/moma.conf
61
81
  - server/testset.xml
62
82
  - tools/cpee-moma
83
+ - ui/css/design.css
84
+ - ui/index.html
85
+ - ui/js/design.js
63
86
  homepage: http://cpee.org/
64
87
  licenses:
65
88
  - LGPL-3.0
@@ -79,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
102
  - !ruby/object:Gem::Version
80
103
  version: '0'
81
104
  requirements: []
82
- rubygems_version: 3.1.4
105
+ rubygems_version: 3.1.6
83
106
  signing_key:
84
107
  specification_version: 4
85
108
  summary: "(Lifecycle) manage your process models in a directory or git repo."