type: 'number',\r
source: {\r
type: 'model',\r
- args: {\r
- select_item_name: 'writing_format_items',\r
- },\r
},\r
rules : {\r
required: true,\r
},\r
select_items: {\r
type: 'system_resource',\r
+ args: {\r
+ select_item_name: 'panel_visible_items',\r
+ },\r
},\r
},\r
},\r
@system_resources = {\r
engine_resources: {\r
license_groups: {\r
- PettanrCreativeCommonsV30Licenses: 'pettanr_creative_commons_v30_licenses',\r
- PettanrPettanCommonsV01Licenses: 'pettanr_pettan_commons_v01_licenses',\r
- PettanrPettanProtectedV01Licenses: 'pettanr_pettan_protected_v01_licenses',\r
- PettanrPettanPublicV01Licenses: 'pettanr_pettan_public_v01_licenses',\r
- PettanrPublicDomainV01Licenses: 'pettanr_public_domain_v01_licenses',\r
- PettanrUnknownV01Licenses: 'pettanr_unknown_v01_licenses',\r
+ resource_items: {\r
+ PettanrCreativeCommonsV30Licenses: 'pettanr_creative_commons_v30_licenses',\r
+ PettanrPettanCommonsV01Licenses: 'pettanr_pettan_commons_v01_licenses',\r
+ PettanrPettanProtectedV01Licenses: 'pettanr_pettan_protected_v01_licenses',\r
+ PettanrPettanPublicV01Licenses: 'pettanr_pettan_public_v01_licenses',\r
+ PettanrPublicDomainV01Licenses: 'pettanr_public_domain_v01_licenses',\r
+ PettanrUnknownV01Licenses: 'pettanr_unknown_v01_licenses',\r
+ },\r
},\r
speech_balloon_templates: {\r
- CircleSpeechBalloon: 'circle_speech_balloon',\r
- PlainSpeechBalloon: 'plain_speech_balloon',\r
- SquareSpeechBalloon: 'square_speech_balloon',\r
- # TestSpeechBalloon: 'test_speech_balloon',\r
+ resource_items: {\r
+ CircleSpeechBalloon: 'circle_speech_balloon',\r
+ PlainSpeechBalloon: 'plain_speech_balloon',\r
+ SquareSpeechBalloon: 'square_speech_balloon',\r
+ # TestSpeechBalloon: 'test_speech_balloon',\r
+ },\r
},\r
writing_formats: {\r
- SimpleFormat: 'pettanr_simple_format',\r
+ has_route: 0,\r
+ resource_items: {\r
+ SimpleFormat: 'pettanr_simple_format',\r
+ },\r
},\r
},\r
elements: {\r
GroundPicture: 'ground_pictures',\r
GroundColor: 'ground_colors',\r
},\r
-}\r
-@magic_numbers = {\r
- run_mode: 1, \r
- thumbnail_width: 64, \r
- thumbnail_height: 64, \r
- profile: {\r
- users: {\r
- caption: "ペンギン王国",\r
- url: "http://localhost:3001/", \r
- description: "ペンギン王国はペンギン素材を豊富に用意したペンギンマニアのサイトです。",\r
- },\r
- admins: {\r
- caption: "site name for admin",\r
- url: "http://your.site.url/admins/", \r
- description: "admin register",\r
- },\r
- demand_users: {\r
- caption: "provider name",\r
- url: "http://your.site.url/demanders/", \r
- description: "provider description",\r
- },\r
- },\r
- provider_sources: [\r
- 'http://sourceforge.jp/projects/pettanr/wiki/ProviderSource/attach/provider_source.json'\r
- ], \r
-}\r
-@select_items = {\r
- model_loader: {\r
- writing_format_items: {\r
- model_name: 'writing_format',\r
- list_name: 'select_items',\r
- caption_name: 'caption'\r
- },\r
- license_group_items: {\r
- model_name: 'license_group',\r
- list_name: 'select_items',\r
- caption_name: 'caption'\r
- },\r
- speech_balloon_template_items: {\r
- model_name: 'speech_balloon_template',\r
- list_name: 'select_items',\r
- caption_name: 'caption'\r
- },\r
- },\r
- magic_number: {\r
+ select_items: {\r
provider_status_status_items: [\r
['select_items.provider_status.status.waiting', 0], \r
['select_items.provider_status.status.receiving', 1], \r
['select_items.speeches.text_align.right', 2], \r
['select_items.speeches.text_align.center', 3], \r
],\r
+ }\r
+}\r
+@magic_numbers = {\r
+ run_mode: 1, \r
+ thumbnail_width: 64, \r
+ thumbnail_height: 64, \r
+ profile: {\r
+ users: {\r
+ caption: "ペンギン王国",\r
+ url: "http://localhost:3001/", \r
+ description: "ペンギン王国はペンギン素材を豊富に用意したペンギンマニアのサイトです。",\r
+ },\r
+ admins: {\r
+ caption: "site name for admin",\r
+ url: "http://your.site.url/admins/", \r
+ description: "admin register",\r
+ },\r
+ demand_users: {\r
+ caption: "provider name",\r
+ url: "http://your.site.url/demanders/", \r
+ description: "provider description",\r
+ },\r
},\r
+ provider_sources: [\r
+ 'http://sourceforge.jp/projects/pettanr/wiki/ProviderSource/attach/provider_source.json'\r
+ ], \r
}\r
models: window.models,\r
system_resources: window.system_resources,\r
magic_numbers: window.magic_numbers,\r
- select_items: window.select_items,\r
locals: {\r
profilers: window.profilers,\r
filers: window.filers,\r
end
def t_selected_item(name, index)
- t(manifest.select_items['magic_number'][name][index][0])
+ t(manifest.system_resources.select_items[name][index][0])
end
def item_tag
{:include => {:licenses => {}}}
end
+ def my_engine_resource
+ Manifest.manifest.system_resources.engine_resources['system_resources']
+ end
+
def engine_name
- Pettanr::Application.manifest.system_resources.license_groups[self.classname]
+ self.my_engine_resource.resource_items[self.classname]
end
def enable?
- Pettanr::Application.manifest.system_resources.license_groups.include? self.classname
+ self.my_engine_resource.resource_items.include? self.classname
end
def engine_module_name
@template_settings ||= JSON.parse(self.settings)
end
+ def my_engine_resource
+ Manifest.manifest.system_resources.engine_resources['speech_balloon_templates']
+ end
+
def engine_name
- Manifest.manifest.system_resources.speech_balloon_templates[self.classname]
+ self.my_engine_resource.resource_items[self.classname]
end
def enable?
- Manifest.manifest.system_resources.speech_balloon_templates.include? self.classname
+ self.my_engine_resource.resource_items.include? self.classname
end
def engine_module_name
@parsed_settings ||= JSON.parse(self.settings)
end
+ def my_engine_resource
+ Manifest.manifest.system_resources.engine_resources['writing_formats']
+ end
+
def engine_name
- Manifest.manifest.system_resources.writing_formats[self.classname]
+ self.my_engine_resource.resource_items[self.classname]
end
def enable?
- Manifest.manifest.system_resources.writing_formats.include? self.classname
+ self.my_engine_resource.resource_items.include? self.classname
end
def engine_module_name
</div>
<div class="field">
<%= f.label :visible %><br />
- <%= f.collection_select :visible, t_select_items(manifest.select_items['magic_number']['comic_visible_items']), :last, :first, :html => {:selected => @comic.visible} %>
+ <%= f.collection_select :visible, t_select_items(manifest.system_resources.select_items['comic_visible_items']), :last, :first, :html => {:selected => @comic.visible} %>
</div>
<div class="row_break">
</div>
</div>
<div class="field">
<%= f.label :orientation %>
- <%= f.collection_select :orientation, t_select_items(MagicNumber['ground_color_orientation_items']), :last, :first, :html => {:selected => elm.orientation} %>
+ <%= f.collection_select :orientation, t_select_items(manifest.system_resources.select_items['ground_color_orientation_items']), :last, :first, :html => {:selected => elm.orientation} %>
<%= f.label :xy %>
<%= f.number_field :xy, elm.field_tag_attributes(:xy, no_attr, :size => 5) %>
</div>
<div class="field">
<%= f.label :repeat %>
- <%= f.collection_select :repeat, t_select_items(manifest.select_items['magic_number']['ground_picture_repeat_items']), *elm.select_tag_attributes(elm.repeat, :repeat, no_attr) %>
+ <%= f.collection_select :repeat, t_select_items(manifest.system_resources.select_items['ground_picture_repeat_items']), *elm.select_tag_attributes(elm.repeat, :repeat, no_attr) %>
</div>
<div class="row_break">
</div>
</div>
<div class="field">
<%= f.label :publish %>
- <%= f.select :publish, t_select_items(manifest.select_items['magic_number']['panel_visible_items']), *@panel.select_tag_attributes(@panel.publish, :publish, 'data-model' => 'panel') %>
+ <%= f.select :publish, t_select_items(manifest.system_resources.select_items['panel_visible_items']), *@panel.select_tag_attributes(@panel.publish, :publish, 'data-model' => 'panel') %>
</div>
<div class="row_break">
</div>
</div>
<div class="field">
<%= f.label :visible %><br />
- <%= f.collection_select :visible, t_select_items(MagicNumber['scroll_visible_items']), :last, :first, :html => {:selected => @scroll.visible} %>
+ <%= f.collection_select :visible, t_select_items(manifest.system_resources.select_items['scroll_visible_items']), :last, :first, :html => {:selected => @scroll.visible} %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<div class="field">
<%= f.label :visible %><br />
- <%= f.select :visible, t_select_items(manifest.select_items['magic_number']['scroll_visible_items']), :html => {:selected => @scroll.visible} %>
+ <%= f.select :visible, t_select_items(manifest.system_resources.select_items['scroll_visible_items']), :html => {:selected => @scroll.visible} %>
</div>
<div class="row_break">
</div>
</div>
<div class="field">
<%= f.label :visible %>
- <%= f.collection_select :visible, t_select_items(MagicNumber['sheet_visible_items']), :last, :first, {:html => {:selected => @sheet.visible}}, {:id => @sheet.field_tag_id(:visible), :sheet_id => @sheet.tag_sheet_id, :column => :visible} %>
+ <%= f.collection_select :visible, t_select_items(manifest.system_resources.select_items['sheet_visible_items']), :last, :first, {:html => {:selected => @sheet.visible}}, {:id => @sheet.field_tag_id(:visible), :sheet_id => @sheet.tag_sheet_id, :column => :visible} %>
</div>
<div class="row_break">
</div>
</div>
<div class="field">
<%= f.label :visible %><br />
- <%= f.collection_select :visible, t_select_items(manifest.select_items['magic_number']['story_visible_items']), :last, :first, :html => {:selected => @story.visible} %>
+ <%= f.collection_select :visible, t_select_items(manifest.system_resources.select_items['story_visible_items']), :last, :first, :html => {:selected => @story.visible} %>
</div>
<div class="row_break">
</div>
devise_for :admins
devise_for :demand_users
- Manifest.manifest.system_resources.license_groups.each do |klass, name|
- p klass
- mount Module.const_get(klass)::Engine => "/#{name}"
- end
- Manifest.manifest.system_resources.speech_balloon_templates.each do |klass , name|
- mount Module.const_get(klass)::Engine => "/#{name}"
+ Manifest.manifest.system_resources.engine_resources.each do |engine_resource_name, engine_resource|
+ if engine_resource.add_route?
+ engine_resource.resource_items.each do |klass, name|
+ mount Module.const_get(klass)::Engine => "/#{name}"
+ end
+ end
end
resources :scrolls do
module Manifest
module ListModule
class SystemResourceList < Base
+ attr :select_item_name
def set_default
super
def init
super
+ @select_item_name = @list_manifest['select_item_name']
end
def items options, offset, page_size
module Manifest
class Manifest
cattr_accessor :manifest
- attr :system_resources, :magic_numbers, :select_items,
+ attr :system_resources, :magic_numbers,
:controllers, :models, :lists, :profilers, :filers, :forms, :lists, :views
# call me before load routes.rb
# routes.rb needs engine_resources manifest in system_resources
@manifest = manifest || {}
@system_resources = SystemResources.new(self, SystemResources.set_default(@manifest['system_resources']))
@magic_numbers = @manifest['magic_numbers']
- @select_items = @manifest['select_items']
end
def init
@forms = Form.base_manager(self, @locals['forms'])
@forms.merge(Form.extend_manager(self, @locals['forms']))
@lists = List.manager(self, @locals['lists'])
- select_items_loader
+ @system_resources.init
add_action
end
- # call after load app
- def select_items_loader
- @system_resources.select_items['model_loader'].each {|name, conf|
- raise "undefined model_name for select_items > model_loader > #{name}\n" unless conf['model_name']
- model_name = conf['model_name']
- list_name = conf['list_name'] || 'select_items'
- caption = conf['caption_name'] || 'caption'
- list_group = @lists[model_name]
- raise "undefined list for select_items > model_loader > #{name} > model_name > #{model_name} \n" unless list_group
- list = list_group[list_name]
- raise "undefined list for select_items > model_loader > #{name} > list_name > #{list_name} \n" unless list
- @select_items['model'] ||= {}
- r = list.open operators, options
- @select_items['model'][name] = r.items.map {|item| [item.attributes[caption], item.id]}
- }
- end
-
def add_action
return
@controllers.each do |controller_name, controller|
module AttributeModule
module SourceModule
class MagicNumberSource
- attr :attribute, :source_manifest
+ attr :attribute, :source_manifest, :type, :select_item_name
def initialize attribute, source_manifest
@attribute = attribute
def set_default
@source_manifest['args'] ||= {}
- @source_manifest['args']['type'] ||= 'magic_number'
raise "undefined select_item_name for models > #{@attribute.model_name} > attributes > #{@attribute.attribute_name} > source\n" unless @source_manifest['args']['select_item_name']
end
def init
@args = @source_manifest['args']
- @type = @args['type']
+ @type = @source_manifest['type']
@select_item_name = @args['select_item_name']
end
module AttributeModule
module SourceModule
class ModelSource
- attr :attribute, :source_manifest
+ attr :attribute, :source_manifest, :type,
+ :resource_model_name, :resource_list_name, :select_item_name, :caption_name
def initialize attribute, source_manifest
@attribute = attribute
def set_default
@source_manifest['args'] ||= {}
- @source_manifest['args']['type'] ||= 'model'
- raise "undefined select_item_name for models > #{@attribute.model_name} > attributes > #{@attribute.attribute_name} > source\n" unless @source_manifest['args']['select_item_name']
+ @source_manifest['args']['resource_model_name'] ||= (@attribute.attribute_name.gsub('_id', ''))
+ @source_manifest['args']['resource_list_name'] ||= 'select_items'
+ @source_manifest['args']['select_item_name'] ||= self.model_name + '_' + self.attribute_name.gsub('_id', '') + '_items'
+ @source_manifest['args']['caption_name'] ||= 'caption'
end
def init
@args = @source_manifest['args']
- @type = @args['type']
+ @type = @source_manifest['type']
+ @resource_model_name = @args['resource_model_name']
+ @resource_list_name = @args['resource_list_name']
@select_item_name = @args['select_item_name']
+ @caption_name = @args['caption_name']
end
def model_name
module ModelModule
module ListModule
class SystemResourceList < Base
+ attr :list_name
def set_default
super
+ @list_manifest['args']['list_name'] ||= 'select_items'
end
def init
super
+ @list_name = @args['list_name']
end
def items
--- /dev/null
+module Manifest
+ module SystemResourceModule
+ class EngineResource
+ def self.manager manifest, my_manifests
+ engine_resources = {}
+ my_manifests.each {|engine_resource_name, engine_resource_manifest|
+ engine_resources[engine_resource_name] = self.new(manifest, engine_resource_name, engine_resource_manifest)
+ }
+ engine_resources
+ end
+
+ attr :engine_resource_name, :engine_resource_manifest,
+ :resource_items, :has_route
+ def initialize manifest, engine_resource_name, engine_resource_manifest
+ @manifest = manifest
+ @engine_resource_name = engine_resource_name
+ @engine_resource_manifest = engine_resource_manifest
+ self.set_default
+ self.init
+ end
+
+ def set_default
+ @engine_resource_manifest['resource_items'] ||= {}
+ @engine_resource_manifest['has_route'] ||= 1
+ end
+
+ def init
+ @resource_items = @engine_resource_manifest['resource_items']
+ @has_route = @engine_resource_manifest['has_route']
+ end
+
+ def add_route?
+ @has_route > 0
+ end
+
+ end
+ end
+end
+
+require_dependency "manifest/system_resource/engine_resource"
module Manifest
class SystemResources
+ include SystemResourceModule
def self.set_default system_resources_manifest
system_resources_manifest['engine_resources'] ||= {}
- system_resources_manifest['license_groups'] ||= {}
- system_resources_manifest['speech_balloon_templates'] ||= {}
- system_resources_manifest['writing_formats'] ||= {}
system_resources_manifest['elements'] ||= {}
system_resources_manifest['select_items'] ||= {}
- system_resources_manifest['select_items']['model_loader'] ||= {}
- system_resources_manifest['select_items']['magic_number'] ||= {}
#oh my ...
#JSON.stringify couldn't print 1.0
# 1 == 1.0 ?
#change class
- system_resources_manifest['select_items']['magic_number']['speech_font_size_items'] ||= {}
- system_resources_manifest['select_items']['magic_number']['speech_font_size_items'].each {|conf|
+ system_resources_manifest['select_items']['speech_font_size_items'] ||= {}
+ system_resources_manifest['select_items']['speech_font_size_items'].each {|conf|
conf[1] = conf[1].to_f
}
system_resources_manifest
end
- attr :engine_resources, :license_groups, :speech_balloon_templates, :writing_formats, :elements, :select_items
+ attr :engine_resources, :elements, :select_items
def initialize manifest, system_resources_manifest
@manifest = manifest
- @engine_resources = system_resources_manifest['engine_resources']
- @license_groups = system_resources_manifest['license_groups']
- @speech_balloon_templates = system_resources_manifest['speech_balloon_templates']
- @writing_formats = system_resources_manifest['writing_formats']
+ @system_resources_manifest = system_resources_manifest
+ @engine_resources = EngineResource.manager(self, @system_resources_manifest['engine_resources'])
@elements = system_resources_manifest['elements']
@select_items = system_resources_manifest['select_items']
end
+ # call after load app
+ def init
+ self.select_items_loader
+ end
+
+ def select_items_loader
+ @manifest.models.each {|model_name, model_manifest|
+ model_manifest.attributes.each {|attribute_name, attribute_manifest|
+ source_manifest = attribute_manifest.source
+ next unless source_manifest
+ next unless source_manifest.type == 'model'
+ resource_model_name = source_manifest.resource_model_name
+ resource_list_name = source_manifest.resource_list_name
+ caption = source_manifest.caption_name
+ list_group = @manifest.lists[resource_model_name]
+ raise "undefined resource model list for lists > #{resource_model_name}\n" unless list_group
+ list = list_group[resource_list_name]
+ raise "undefined resource list for lists > #{resource_model_name} > #{resource_list_name}\n" unless list
+ r = list.open nil, {}
+ @select_items[source_manifest.select_item_name] =
+ r.items.map {|item| [item.attributes[caption], item.id]}
+ }
+ }
+ end
+
end
end
"writing_format_id": {\r
"type": "number",\r
"source": {\r
- "type": "model",\r
- "args": {\r
- "select_item_name": "writing_format_items"\r
- }\r
+ "type": "model"\r
},\r
"rules": {\r
"required": true,\r
"type": "public"\r
},\r
"select_items": {\r
- "type": "system_resource"\r
+ "type": "system_resource",\r
+ "args": {\r
+ "select_item_name": "panel_visible_items"\r
+ }\r
}\r
}\r
},\r
"system_resources": {\r
"engine_resources": {\r
"license_groups": {\r
- "PettanrCreativeCommonsV30Licenses": "pettanr_creative_commons_v30_licenses",\r
- "PettanrPettanCommonsV01Licenses": "pettanr_pettan_commons_v01_licenses",\r
- "PettanrPettanProtectedV01Licenses": "pettanr_pettan_protected_v01_licenses",\r
- "PettanrPettanPublicV01Licenses": "pettanr_pettan_public_v01_licenses",\r
- "PettanrPublicDomainV01Licenses": "pettanr_public_domain_v01_licenses",\r
- "PettanrUnknownV01Licenses": "pettanr_unknown_v01_licenses"\r
+ "resource_items": {\r
+ "PettanrCreativeCommonsV30Licenses": "pettanr_creative_commons_v30_licenses",\r
+ "PettanrPettanCommonsV01Licenses": "pettanr_pettan_commons_v01_licenses",\r
+ "PettanrPettanProtectedV01Licenses": "pettanr_pettan_protected_v01_licenses",\r
+ "PettanrPettanPublicV01Licenses": "pettanr_pettan_public_v01_licenses",\r
+ "PettanrPublicDomainV01Licenses": "pettanr_public_domain_v01_licenses",\r
+ "PettanrUnknownV01Licenses": "pettanr_unknown_v01_licenses"\r
+ }\r
},\r
"speech_balloon_templates": {\r
- "CircleSpeechBalloon": "circle_speech_balloon",\r
- "PlainSpeechBalloon": "plain_speech_balloon",\r
- "SquareSpeechBalloon": "square_speech_balloon"\r
+ "resource_items": {\r
+ "CircleSpeechBalloon": "circle_speech_balloon",\r
+ "PlainSpeechBalloon": "plain_speech_balloon",\r
+ "SquareSpeechBalloon": "square_speech_balloon"\r
+ }\r
},\r
"writing_formats": {\r
- "SimpleFormat": "pettanr_simple_format"\r
+ "has_route": 0,\r
+ "resource_items": {\r
+ "SimpleFormat": "pettanr_simple_format"\r
+ }\r
}\r
},\r
"elements": {\r
"SpeechBalloon": "speech_balloons",\r
"GroundPicture": "ground_pictures",\r
"GroundColor": "ground_colors"\r
- }\r
- },\r
- "magic_numbers": {\r
- "run_mode": 1,\r
- "thumbnail_width": 64,\r
- "thumbnail_height": 64,\r
- "profile": {\r
- "users": {\r
- "caption": "ペンギン王国",\r
- "url": "http://localhost:3001/",\r
- "description": "ペンギン王国はペンギン素材を豊富に用意したペンギンマニアのサイトです。"\r
- },\r
- "admins": {\r
- "caption": "site name for admin",\r
- "url": "http://your.site.url/admins/",\r
- "description": "admin register"\r
- },\r
- "demand_users": {\r
- "caption": "provider name",\r
- "url": "http://your.site.url/demanders/",\r
- "description": "provider description"\r
- }\r
- },\r
- "provider_sources": [\r
- "http://sourceforge.jp/projects/pettanr/wiki/ProviderSource/attach/provider_source.json"\r
- ]\r
- },\r
- "select_items": {\r
- "model_loader": {\r
- "writing_format_items": {\r
- "model_name": "writing_format",\r
- "list_name": "select_items",\r
- "caption_name": "caption"\r
- },\r
- "license_group_items": {\r
- "model_name": "license_group",\r
- "list_name": "select_items",\r
- "caption_name": "caption"\r
- },\r
- "speech_balloon_template_items": {\r
- "model_name": "speech_balloon_template",\r
- "list_name": "select_items",\r
- "caption_name": "caption"\r
- }\r
},\r
- "magic_number": {\r
+ "select_items": {\r
"provider_status_status_items": [\r
[\r
"select_items.provider_status.status.waiting",\r
]\r
}\r
},\r
+ "magic_numbers": {\r
+ "run_mode": 1,\r
+ "thumbnail_width": 64,\r
+ "thumbnail_height": 64,\r
+ "profile": {\r
+ "users": {\r
+ "caption": "ペンギン王国",\r
+ "url": "http://localhost:3001/",\r
+ "description": "ペンギン王国はペンギン素材を豊富に用意したペンギンマニアのサイトです。"\r
+ },\r
+ "admins": {\r
+ "caption": "site name for admin",\r
+ "url": "http://your.site.url/admins/",\r
+ "description": "admin register"\r
+ },\r
+ "demand_users": {\r
+ "caption": "provider name",\r
+ "url": "http://your.site.url/demanders/",\r
+ "description": "provider description"\r
+ }\r
+ },\r
+ "provider_sources": [\r
+ "http://sourceforge.jp/projects/pettanr/wiki/ProviderSource/attach/provider_source.json"\r
+ ]\r
+ },\r
"locals": {\r
"profilers": {\r
"scroll": {\r
}\r
},\r
"caption": {\r
- "type": "default",\r
- "args": {\r
- "face": {\r
- "type": "none",\r
- "args": {}\r
- },\r
- "link": {\r
- "type": "none",\r
- "args": {}\r
- }\r
- }\r
+ "type": "none",\r
+ "args": {}\r
},\r
"summary": {\r
"type": "template",\r