from __future__ import print_function,absolute_import,division
_e='tag:yaml.org,2002:'
_d='state'
_c='args'
_b='tag:yaml.org,2002:python/object:'
_a='__getstate__'
_Z='tag:yaml.org,2002:set'
_Y='-.inf'
_X='.inf'
_W='.nan'
_V='base64'
_U='utf-8'
_T='null'
_S='typ'
_R='tag:yaml.org,2002:python/object/new:'
_Q='tag:yaml.org,2002:timestamp'
_P='tag:yaml.org,2002:map'
_O='tag:yaml.org,2002:seq'
_N='tag:yaml.org,2002:float'
_M='tag:yaml.org,2002:binary'
_L='tag:yaml.org,2002:null'
_K=0.0
_J='|'
_I='%s.%s'
_H='.'
_G='tag:yaml.org,2002:int'
_F='comment'
_E='ascii'
_D='tag:yaml.org,2002:str'
_C=False
_B=True
_A=None
from .error import *
from .nodes import *
from .compat import text_type,binary_type,to_unicode,PY2,PY3
from .compat import ordereddict
from .compat import nprint,nprintf
from .scalarstring import LiteralScalarString,FoldedScalarString,SingleQuotedScalarString,DoubleQuotedScalarString,PlainScalarString
from .scalarint import ScalarInt,BinaryInt,OctalInt,HexInt,HexCapsInt
from .scalarfloat import ScalarFloat
from .scalarbool import ScalarBoolean
from .timestamp import TimeStamp
import datetime,sys,types
if PY3:import copyreg,base64
else:import copy_reg as copyreg
if _C:from typing import Dict,List,Any,Union,Text,Optional
__all__=['BaseRepresenter','SafeRepresenter','Representer','RepresenterError','RoundTripRepresenter']
class RepresenterError(YAMLError):0
if PY2:
	def get_classobj_bases(cls):
		bases=[cls]
		for base in cls.__bases__:bases.extend(get_classobj_bases(base))
		return bases
class BaseRepresenter:
	yaml_representers={};yaml_multi_representers={}
	def __init__(self,default_style=_A,default_flow_style=_A,dumper=_A):
		self.dumper=dumper
		if self.dumper is not _A:self.dumper._representer=self
		self.default_style=default_style;self.default_flow_style=default_flow_style;self.represented_objects={};self.object_keeper=[];self.alias_key=_A;self.sort_base_mapping_type_on_output=_B
	@property
	def serializer(self):
		try:
			if hasattr(self.dumper,_S):return self.dumper.serializer
			return self.dumper._serializer
		except AttributeError:return self
	def represent(self,data):node=self.represent_data(data);self.serializer.serialize(node);self.represented_objects={};self.object_keeper=[];self.alias_key=_A
	def represent_data(self,data):
		if self.ignore_aliases(data):self.alias_key=_A
		else:self.alias_key=id(data)
		if self.alias_key is not _A:
			if self.alias_key in self.represented_objects:node=self.represented_objects[self.alias_key];return node
			self.object_keeper.append(data)
		data_types=type(data).__mro__
		if PY2:
			if isinstance(data,types.InstanceType):data_types=get_classobj_bases(data.__class__)+list(data_types)
		if data_types[0]in self.yaml_representers:node=self.yaml_representers[data_types[0]](self,data)
		else:
			for data_type in data_types:
				if data_type in self.yaml_multi_representers:node=self.yaml_multi_representers[data_type](self,data);break
			else:
				if _A in self.yaml_multi_representers:node=self.yaml_multi_representers[_A](self,data)
				elif _A in self.yaml_representers:node=self.yaml_representers[_A](self,data)
				else:node=ScalarNode(_A,text_type(data))
		return node
	def represent_key(self,data):return self.represent_data(data)
	@classmethod
	def add_representer(cls,data_type,representer):
		if'yaml_representers'not in cls.__dict__:cls.yaml_representers=cls.yaml_representers.copy()
		cls.yaml_representers[data_type]=representer
	@classmethod
	def add_multi_representer(cls,data_type,representer):
		if'yaml_multi_representers'not in cls.__dict__:cls.yaml_multi_representers=cls.yaml_multi_representers.copy()
		cls.yaml_multi_representers[data_type]=representer
	def represent_scalar(self,tag,value,style=_A,anchor=_A):
		if style is _A:style=self.default_style
		comment=_A
		if style and style[0]in'|>':
			comment=getattr(value,_F,_A)
			if comment:comment=[_A,[comment]]
		node=ScalarNode(tag,value,style=style,comment=comment,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		return node
	def represent_sequence(self,tag,sequence,flow_style=_A):
		value=[];node=SequenceNode(tag,value,flow_style=flow_style)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		for item in sequence:
			node_item=self.represent_data(item)
			if not(isinstance(node_item,ScalarNode)and not node_item.style):best_style=_C
			value.append(node_item)
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def represent_omap(self,tag,omap,flow_style=_A):
		value=[];node=SequenceNode(tag,value,flow_style=flow_style)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		for item_key in omap:item_val=omap[item_key];node_item=self.represent_data({item_key:item_val});value.append(node_item)
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def represent_mapping(self,tag,mapping,flow_style=_A):
		value=[];node=MappingNode(tag,value,flow_style=flow_style)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		if hasattr(mapping,'items'):
			mapping=list(mapping.items())
			if self.sort_base_mapping_type_on_output:
				try:mapping=sorted(mapping)
				except TypeError:pass
		for (item_key,item_value) in mapping:
			node_key=self.represent_key(item_key);node_value=self.represent_data(item_value)
			if not(isinstance(node_key,ScalarNode)and not node_key.style):best_style=_C
			if not(isinstance(node_value,ScalarNode)and not node_value.style):best_style=_C
			value.append((node_key,node_value))
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def ignore_aliases(self,data):return _C
class SafeRepresenter(BaseRepresenter):
	def ignore_aliases(self,data):
		if data is _A or isinstance(data,tuple)and data==():return _B
		if isinstance(data,(binary_type,text_type,bool,int,float)):return _B
		return _C
	def represent_none(self,data):return self.represent_scalar(_L,_T)
	if PY3:
		def represent_str(self,data):return self.represent_scalar(_D,data)
		def represent_binary(self,data):
			if hasattr(base64,'encodebytes'):data=base64.encodebytes(data).decode(_E)
			else:data=base64.encodestring(data).decode(_E)
			return self.represent_scalar(_M,data,style=_J)
	else:
		def represent_str(self,data):
			tag=_A;style=_A
			try:data=unicode(data,_E);tag=_D
			except UnicodeDecodeError:
				try:data=unicode(data,_U);tag=_D
				except UnicodeDecodeError:data=data.encode(_V);tag=_M;style=_J
			return self.represent_scalar(tag,data,style=style)
		def represent_unicode(self,data):return self.represent_scalar(_D,data)
	def represent_bool(self,data,anchor=_A):
		try:value=self.dumper.boolean_representation[bool(data)]
		except AttributeError:
			if data:value='true'
			else:value='false'
		return self.represent_scalar('tag:yaml.org,2002:bool',value,anchor=anchor)
	def represent_int(self,data):return self.represent_scalar(_G,text_type(data))
	if PY2:
		def represent_long(self,data):return self.represent_scalar(_G,text_type(data))
	inf_value=1e+300
	while repr(inf_value)!=repr(inf_value*inf_value):inf_value*=inf_value
	def represent_float(self,data):
		if data!=data or data==_K and data==1.0:value=_W
		elif data==self.inf_value:value=_X
		elif data==-self.inf_value:value=_Y
		else:
			value=to_unicode(repr(data)).lower()
			if getattr(self.serializer,'use_version',_A)==(1,1):
				if _H not in value and'e'in value:value=value.replace('e','.0e',1)
		return self.represent_scalar(_N,value)
	def represent_list(self,data):return self.represent_sequence(_O,data)
	def represent_dict(self,data):return self.represent_mapping(_P,data)
	def represent_ordereddict(self,data):return self.represent_omap('tag:yaml.org,2002:omap',data)
	def represent_set(self,data):
		value={}
		for key in data:value[key]=_A
		return self.represent_mapping(_Z,value)
	def represent_date(self,data):value=to_unicode(data.isoformat());return self.represent_scalar(_Q,value)
	def represent_datetime(self,data):value=to_unicode(data.isoformat(' '));return self.represent_scalar(_Q,value)
	def represent_yaml_object(self,tag,data,cls,flow_style=_A):
		if hasattr(data,_a):state=data.__getstate__()
		else:state=data.__dict__.copy()
		return self.represent_mapping(tag,state,flow_style=flow_style)
	def represent_undefined(self,data):raise RepresenterError('cannot represent an object: %s'%(data,))
SafeRepresenter.add_representer(type(_A),SafeRepresenter.represent_none)
SafeRepresenter.add_representer(str,SafeRepresenter.represent_str)
if PY2:SafeRepresenter.add_representer(unicode,SafeRepresenter.represent_unicode)
else:SafeRepresenter.add_representer(bytes,SafeRepresenter.represent_binary)
SafeRepresenter.add_representer(bool,SafeRepresenter.represent_bool)
SafeRepresenter.add_representer(int,SafeRepresenter.represent_int)
if PY2:SafeRepresenter.add_representer(long,SafeRepresenter.represent_long)
SafeRepresenter.add_representer(float,SafeRepresenter.represent_float)
SafeRepresenter.add_representer(list,SafeRepresenter.represent_list)
SafeRepresenter.add_representer(tuple,SafeRepresenter.represent_list)
SafeRepresenter.add_representer(dict,SafeRepresenter.represent_dict)
SafeRepresenter.add_representer(set,SafeRepresenter.represent_set)
SafeRepresenter.add_representer(ordereddict,SafeRepresenter.represent_ordereddict)
if sys.version_info>=(2,7):import collections;SafeRepresenter.add_representer(collections.OrderedDict,SafeRepresenter.represent_ordereddict)
SafeRepresenter.add_representer(datetime.date,SafeRepresenter.represent_date)
SafeRepresenter.add_representer(datetime.datetime,SafeRepresenter.represent_datetime)
SafeRepresenter.add_representer(_A,SafeRepresenter.represent_undefined)
class Representer(SafeRepresenter):
	if PY2:
		def represent_str(self,data):
			tag=_A;style=_A
			try:data=unicode(data,_E);tag=_D
			except UnicodeDecodeError:
				try:data=unicode(data,_U);tag='tag:yaml.org,2002:python/str'
				except UnicodeDecodeError:data=data.encode(_V);tag=_M;style=_J
			return self.represent_scalar(tag,data,style=style)
		def represent_unicode(self,data):
			tag=_A
			try:data.encode(_E);tag='tag:yaml.org,2002:python/unicode'
			except UnicodeEncodeError:tag=_D
			return self.represent_scalar(tag,data)
		def represent_long(self,data):
			tag=_G
			if int(data)is not data:tag='tag:yaml.org,2002:python/long'
			return self.represent_scalar(tag,to_unicode(data))
	def represent_complex(self,data):
		if data.imag==_K:data='%r'%data.real
		elif data.real==_K:data='%rj'%data.imag
		elif data.imag>0:data='%r+%rj'%(data.real,data.imag)
		else:data='%r%rj'%(data.real,data.imag)
		return self.represent_scalar('tag:yaml.org,2002:python/complex',data)
	def represent_tuple(self,data):return self.represent_sequence('tag:yaml.org,2002:python/tuple',data)
	def represent_name(self,data):
		try:name=_I%(data.__module__,data.__qualname__)
		except AttributeError:name=_I%(data.__module__,data.__name__)
		return self.represent_scalar('tag:yaml.org,2002:python/name:'+name,'')
	def represent_module(self,data):return self.represent_scalar('tag:yaml.org,2002:python/module:'+data.__name__,'')
	if PY2:
		def represent_instance(self,data):
			cls=data.__class__;class_name=_I%(cls.__module__,cls.__name__);args=_A;state=_A
			if hasattr(data,'__getinitargs__'):args=list(data.__getinitargs__())
			if hasattr(data,_a):state=data.__getstate__()
			else:state=data.__dict__
			if args is _A and isinstance(state,dict):return self.represent_mapping(_b+class_name,state)
			if isinstance(state,dict)and not state:return self.represent_sequence(_R+class_name,args)
			value={}
			if bool(args):value[_c]=args
			value[_d]=state;return self.represent_mapping(_R+class_name,value)
	def represent_object(self,data):
		cls=type(data)
		if cls in copyreg.dispatch_table:reduce=copyreg.dispatch_table[cls](data)
		elif hasattr(data,'__reduce_ex__'):reduce=data.__reduce_ex__(2)
		elif hasattr(data,'__reduce__'):reduce=data.__reduce__()
		else:raise RepresenterError('cannot represent object: %r'%(data,))
		reduce=(list(reduce)+[_A]*5)[:5];function,args,state,listitems,dictitems=reduce;args=list(args)
		if state is _A:state={}
		if listitems is not _A:listitems=list(listitems)
		if dictitems is not _A:dictitems=dict(dictitems)
		if function.__name__=='__newobj__':function=args[0];args=args[1:];tag=_R;newobj=_B
		else:tag='tag:yaml.org,2002:python/object/apply:';newobj=_C
		try:function_name=_I%(function.__module__,function.__qualname__)
		except AttributeError:function_name=_I%(function.__module__,function.__name__)
		if not args and not listitems and not dictitems and isinstance(state,dict)and newobj:return self.represent_mapping(_b+function_name,state)
		if not listitems and not dictitems and isinstance(state,dict)and not state:return self.represent_sequence(tag+function_name,args)
		value={}
		if args:value[_c]=args
		if state or not isinstance(state,dict):value[_d]=state
		if listitems:value['listitems']=listitems
		if dictitems:value['dictitems']=dictitems
		return self.represent_mapping(tag+function_name,value)
if PY2:Representer.add_representer(str,Representer.represent_str);Representer.add_representer(unicode,Representer.represent_unicode);Representer.add_representer(long,Representer.represent_long)
Representer.add_representer(complex,Representer.represent_complex)
Representer.add_representer(tuple,Representer.represent_tuple)
Representer.add_representer(type,Representer.represent_name)
if PY2:Representer.add_representer(types.ClassType,Representer.represent_name)
Representer.add_representer(types.FunctionType,Representer.represent_name)
Representer.add_representer(types.BuiltinFunctionType,Representer.represent_name)
Representer.add_representer(types.ModuleType,Representer.represent_module)
if PY2:Representer.add_multi_representer(types.InstanceType,Representer.represent_instance)
Representer.add_multi_representer(object,Representer.represent_object)
Representer.add_multi_representer(type,Representer.represent_name)
from .comments import CommentedMap,CommentedOrderedMap,CommentedSeq,CommentedKeySeq,CommentedKeyMap,CommentedSet,comment_attrib,merge_attrib,TaggedScalar
class RoundTripRepresenter(SafeRepresenter):
	def __init__(self,default_style=_A,default_flow_style=_A,dumper=_A):
		if not hasattr(dumper,_S)and default_flow_style is _A:default_flow_style=_C
		SafeRepresenter.__init__(self,default_style=default_style,default_flow_style=default_flow_style,dumper=dumper)
	def ignore_aliases(self,data):
		try:
			if data.anchor is not _A and data.anchor.value is not _A:return _C
		except AttributeError:pass
		return SafeRepresenter.ignore_aliases(self,data)
	def represent_none(self,data):
		if len(self.represented_objects)==0 and not self.serializer.use_explicit_start:return self.represent_scalar(_L,_T)
		return self.represent_scalar(_L,'')
	def represent_literal_scalarstring(self,data):
		tag=_A;style=_J;anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	represent_preserved_scalarstring=represent_literal_scalarstring
	def represent_folded_scalarstring(self,data):
		tag=_A;style='>';anchor=data.yaml_anchor(any=_B)
		for fold_pos in reversed(getattr(data,'fold_pos',[])):
			if data[fold_pos]==' 'and(fold_pos>0 and not data[fold_pos-1].isspace())and(fold_pos<len(data)and not data[fold_pos+1].isspace()):data=data[:fold_pos]+'\x07'+data[fold_pos:]
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def represent_single_quoted_scalarstring(self,data):
		tag=_A;style="'";anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def represent_double_quoted_scalarstring(self,data):
		tag=_A;style='"';anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def represent_plain_scalarstring(self,data):
		tag=_A;style='';anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def insert_underscore(self,prefix,s,underscore,anchor=_A):
		A='_'
		if underscore is _A:return self.represent_scalar(_G,prefix+s,anchor=anchor)
		if underscore[0]:
			sl=list(s);pos=len(s)-underscore[0]
			while pos>0:sl.insert(pos,A);pos-=underscore[0]
			s=''.join(sl)
		if underscore[1]:s=A+s
		if underscore[2]:s+=A
		return self.represent_scalar(_G,prefix+s,anchor=anchor)
	def represent_scalar_int(self,data):
		if data._width is not _A:s='{:0{}d}'.format(data,data._width)
		else:s=format(data,'d')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('',s,data._underscore,anchor=anchor)
	def represent_binary_int(self,data):
		if data._width is not _A:s='{:0{}b}'.format(data,data._width)
		else:s=format(data,'b')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0b',s,data._underscore,anchor=anchor)
	def represent_octal_int(self,data):
		if data._width is not _A:s='{:0{}o}'.format(data,data._width)
		else:s=format(data,'o')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0o',s,data._underscore,anchor=anchor)
	def represent_hex_int(self,data):
		if data._width is not _A:s='{:0{}x}'.format(data,data._width)
		else:s=format(data,'x')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0x',s,data._underscore,anchor=anchor)
	def represent_hex_caps_int(self,data):
		if data._width is not _A:s='{:0{}X}'.format(data,data._width)
		else:s=format(data,'X')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0x',s,data._underscore,anchor=anchor)
	def represent_scalar_float(self,data):
		C='+';B='{:{}0{}d}';A='0';value=_A;anchor=data.yaml_anchor(any=_B)
		if data!=data or data==_K and data==1.0:value=_W
		elif data==self.inf_value:value=_X
		elif data==-self.inf_value:value=_Y
		if value:return self.represent_scalar(_N,value,anchor=anchor)
		if data._exp is _A and data._prec>0 and data._prec==data._width-1:value='{}{:d}.'.format(data._m_sign if data._m_sign else'',abs(int(data)))
		elif data._exp is _A:
			prec=data._prec;ms=data._m_sign if data._m_sign else'';value='{}{:0{}.{}f}'.format(ms,abs(data),data._width-len(ms),data._width-prec-1)
			if prec==0 or prec==1 and ms!='':value=value.replace('0.',_H)
			while len(value)<data._width:value+=A
		else:
			m,es='{:{}.{}e}'.format(data,data._width,data._width+(1 if data._m_sign else 0)).split('e');w=data._width if data._prec>0 else data._width+1
			if data<0:w+=1
			m=m[:w];e=int(es);m1,m2=m.split(_H)
			while len(m1)+len(m2)<data._width-(1 if data._prec>=0 else 0):m2+=A
			if data._m_sign and data>0:m1=C+m1
			esgn=C if data._e_sign else''
			if data._prec<0:
				if m2!=A:e-=len(m2)
				else:m2=''
				while len(m1)+len(m2)-(1 if data._m_sign else 0)<data._width:m2+=A;e-=1
				value=m1+m2+data._exp+B.format(e,esgn,data._e_width)
			elif data._prec==0:e-=len(m2);value=m1+m2+_H+data._exp+B.format(e,esgn,data._e_width)
			else:
				if data._m_lead0>0:m2=A*(data._m_lead0-1)+m1+m2;m1=A;m2=m2[:-data._m_lead0];e+=data._m_lead0
				while len(m1)<data._prec:m1+=m2[0];m2=m2[1:];e-=1
				value=m1+_H+m2+data._exp+B.format(e,esgn,data._e_width)
		if value is _A:value=to_unicode(repr(data)).lower()
		return self.represent_scalar(_N,value,anchor=anchor)
	def represent_sequence(self,tag,sequence,flow_style=_A):
		value=[]
		try:flow_style=sequence.fa.flow_style(flow_style)
		except AttributeError:flow_style=flow_style
		try:anchor=sequence.yaml_anchor()
		except AttributeError:anchor=_A
		node=SequenceNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(sequence,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			item_comments=comment.items;node.comment=comment.comment
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		for (idx,item) in enumerate(sequence):
			node_item=self.represent_data(item);self.merge_comments(node_item,item_comments.get(idx))
			if not(isinstance(node_item,ScalarNode)and not node_item.style):best_style=_C
			value.append(node_item)
		if flow_style is _A:
			if len(sequence)!=0 and self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def merge_comments(self,node,comments):
		if comments is _A:assert hasattr(node,_F);return node
		if getattr(node,_F,_A)is not _A:
			for (idx,val) in enumerate(comments):
				if idx>=len(node.comment):continue
				nc=node.comment[idx]
				if nc is not _A:assert val is _A or val==nc;comments[idx]=nc
		node.comment=comments;return node
	def represent_key(self,data):
		if isinstance(data,CommentedKeySeq):self.alias_key=_A;return self.represent_sequence(_O,data,flow_style=_B)
		if isinstance(data,CommentedKeyMap):self.alias_key=_A;return self.represent_mapping(_P,data,flow_style=_B)
		return SafeRepresenter.represent_key(self,data)
	def represent_mapping(self,tag,mapping,flow_style=_A):
		value=[]
		try:flow_style=mapping.fa.flow_style(flow_style)
		except AttributeError:flow_style=flow_style
		try:anchor=mapping.yaml_anchor()
		except AttributeError:anchor=_A
		node=MappingNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(mapping,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		merge_list=[m[1]for m in getattr(mapping,merge_attrib,[])]
		try:merge_pos=getattr(mapping,merge_attrib,[[0]])[0][0]
		except IndexError:merge_pos=0
		item_count=0
		if bool(merge_list):items=mapping.non_merged_items()
		else:items=mapping.items()
		for (item_key,item_value) in items:
			item_count+=1;node_key=self.represent_key(item_key);node_value=self.represent_data(item_value);item_comment=item_comments.get(item_key)
			if item_comment:
				assert getattr(node_key,_F,_A)is _A;node_key.comment=item_comment[:2];nvc=getattr(node_value,_F,_A)
				if nvc is not _A:nvc[0]=item_comment[2];nvc[1]=item_comment[3]
				else:node_value.comment=item_comment[2:]
			if not(isinstance(node_key,ScalarNode)and not node_key.style):best_style=_C
			if not(isinstance(node_value,ScalarNode)and not node_value.style):best_style=_C
			value.append((node_key,node_value))
		if flow_style is _A:
			if(item_count!=0 or bool(merge_list))and self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		if bool(merge_list):
			if len(merge_list)==1:arg=self.represent_data(merge_list[0])
			else:arg=self.represent_data(merge_list);arg.flow_style=_B
			value.insert(merge_pos,(ScalarNode('tag:yaml.org,2002:merge','<<'),arg))
		return node
	def represent_omap(self,tag,omap,flow_style=_A):
		value=[]
		try:flow_style=omap.fa.flow_style(flow_style)
		except AttributeError:flow_style=flow_style
		try:anchor=omap.yaml_anchor()
		except AttributeError:anchor=_A
		node=SequenceNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(omap,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		for item_key in omap:
			item_val=omap[item_key];node_item=self.represent_data({item_key:item_val});item_comment=item_comments.get(item_key)
			if item_comment:
				if item_comment[1]:node_item.comment=[_A,item_comment[1]]
				assert getattr(node_item.value[0][0],_F,_A)is _A;node_item.value[0][0].comment=[item_comment[0],_A];nvc=getattr(node_item.value[0][1],_F,_A)
				if nvc is not _A:nvc[0]=item_comment[2];nvc[1]=item_comment[3]
				else:node_item.value[0][1].comment=item_comment[2:]
			value.append(node_item)
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def represent_set(self,setting):
		flow_style=_C;tag=_Z;value=[];flow_style=setting.fa.flow_style(flow_style)
		try:anchor=setting.yaml_anchor()
		except AttributeError:anchor=_A
		node=MappingNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(setting,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		for item_key in setting.odict:
			node_key=self.represent_key(item_key);node_value=self.represent_data(_A);item_comment=item_comments.get(item_key)
			if item_comment:assert getattr(node_key,_F,_A)is _A;node_key.comment=item_comment[:2]
			node_key.style=node_value.style='?'
			if not(isinstance(node_key,ScalarNode)and not node_key.style):best_style=_C
			if not(isinstance(node_value,ScalarNode)and not node_value.style):best_style=_C
			value.append((node_key,node_value))
		best_style=best_style;return node
	def represent_dict(self,data):
		try:t=data.tag.value
		except AttributeError:t=_A
		if t:
			if t.startswith('!!'):tag=_e+t[2:]
			else:tag=t
		else:tag=_P
		return self.represent_mapping(tag,data)
	def represent_list(self,data):
		try:t=data.tag.value
		except AttributeError:t=_A
		if t:
			if t.startswith('!!'):tag=_e+t[2:]
			else:tag=t
		else:tag=_O
		return self.represent_sequence(tag,data)
	def represent_datetime(self,data):
		B='tz';A='delta';inter='T'if data._yaml['t']else' ';_yaml=data._yaml
		if _yaml[A]:data+=_yaml[A];value=data.isoformat(inter)
		else:value=data.isoformat(inter)
		if _yaml[B]:value+=_yaml[B]
		return self.represent_scalar(_Q,to_unicode(value))
	def represent_tagged_scalar(self,data):
		try:tag=data.tag.value
		except AttributeError:tag=_A
		try:anchor=data.yaml_anchor()
		except AttributeError:anchor=_A
		return self.represent_scalar(tag,data.value,style=data.style,anchor=anchor)
	def represent_scalar_bool(self,data):
		try:anchor=data.yaml_anchor()
		except AttributeError:anchor=_A
		return SafeRepresenter.represent_bool(self,data,anchor=anchor)
RoundTripRepresenter.add_representer(type(_A),RoundTripRepresenter.represent_none)
RoundTripRepresenter.add_representer(LiteralScalarString,RoundTripRepresenter.represent_literal_scalarstring)
RoundTripRepresenter.add_representer(FoldedScalarString,RoundTripRepresenter.represent_folded_scalarstring)
RoundTripRepresenter.add_representer(SingleQuotedScalarString,RoundTripRepresenter.represent_single_quoted_scalarstring)
RoundTripRepresenter.add_representer(DoubleQuotedScalarString,RoundTripRepresenter.represent_double_quoted_scalarstring)
RoundTripRepresenter.add_representer(PlainScalarString,RoundTripRepresenter.represent_plain_scalarstring)
RoundTripRepresenter.add_representer(ScalarInt,RoundTripRepresenter.represent_scalar_int)
RoundTripRepresenter.add_representer(BinaryInt,RoundTripRepresenter.represent_binary_int)
RoundTripRepresenter.add_representer(OctalInt,RoundTripRepresenter.represent_octal_int)
RoundTripRepresenter.add_representer(HexInt,RoundTripRepresenter.represent_hex_int)
RoundTripRepresenter.add_representer(HexCapsInt,RoundTripRepresenter.represent_hex_caps_int)
RoundTripRepresenter.add_representer(ScalarFloat,RoundTripRepresenter.represent_scalar_float)
RoundTripRepresenter.add_representer(ScalarBoolean,RoundTripRepresenter.represent_scalar_bool)
RoundTripRepresenter.add_representer(CommentedSeq,RoundTripRepresenter.represent_list)
RoundTripRepresenter.add_representer(CommentedMap,RoundTripRepresenter.represent_dict)
RoundTripRepresenter.add_representer(CommentedOrderedMap,RoundTripRepresenter.represent_ordereddict)
if sys.version_info>=(2,7):import collections;RoundTripRepresenter.add_representer(collections.OrderedDict,RoundTripRepresenter.represent_ordereddict)
RoundTripRepresenter.add_representer(CommentedSet,RoundTripRepresenter.represent_set)
RoundTripRepresenter.add_representer(TaggedScalar,RoundTripRepresenter.represent_tagged_scalar)
RoundTripRepresenter.add_representer(TimeStamp,RoundTripRepresenter.represent_datetime)
from __future__ import print_function,absolute_import,division
_e='tag:yaml.org,2002:'
_d='state'
_c='args'
_b='tag:yaml.org,2002:python/object:'
_a='__getstate__'
_Z='tag:yaml.org,2002:set'
_Y='-.inf'
_X='.inf'
_W='.nan'
_V='base64'
_U='utf-8'
_T='null'
_S='typ'
_R='tag:yaml.org,2002:python/object/new:'
_Q='tag:yaml.org,2002:timestamp'
_P='tag:yaml.org,2002:map'
_O='tag:yaml.org,2002:seq'
_N='tag:yaml.org,2002:float'
_M='tag:yaml.org,2002:binary'
_L='tag:yaml.org,2002:null'
_K=0.0
_J='|'
_I='%s.%s'
_H='.'
_G='tag:yaml.org,2002:int'
_F='comment'
_E='ascii'
_D='tag:yaml.org,2002:str'
_C=False
_B=True
_A=None
from .error import *
from .nodes import *
from .compat import text_type,binary_type,to_unicode,PY2,PY3
from .compat import ordereddict
from .compat import nprint,nprintf
from .scalarstring import LiteralScalarString,FoldedScalarString,SingleQuotedScalarString,DoubleQuotedScalarString,PlainScalarString
from .scalarint import ScalarInt,BinaryInt,OctalInt,HexInt,HexCapsInt
from .scalarfloat import ScalarFloat
from .scalarbool import ScalarBoolean
from .timestamp import TimeStamp
import datetime,sys,types
if PY3:import copyreg,base64
else:import copy_reg as copyreg
if _C:from typing import Dict,List,Any,Union,Text,Optional
__all__=['BaseRepresenter','SafeRepresenter','Representer','RepresenterError','RoundTripRepresenter']
class RepresenterError(YAMLError):0
if PY2:
	def get_classobj_bases(cls):
		bases=[cls]
		for base in cls.__bases__:bases.extend(get_classobj_bases(base))
		return bases
class BaseRepresenter:
	yaml_representers={};yaml_multi_representers={}
	def __init__(self,default_style=_A,default_flow_style=_A,dumper=_A):
		self.dumper=dumper
		if self.dumper is not _A:self.dumper._representer=self
		self.default_style=default_style;self.default_flow_style=default_flow_style;self.represented_objects={};self.object_keeper=[];self.alias_key=_A;self.sort_base_mapping_type_on_output=_B
	@property
	def serializer(self):
		try:
			if hasattr(self.dumper,_S):return self.dumper.serializer
			return self.dumper._serializer
		except AttributeError:return self
	def represent(self,data):node=self.represent_data(data);self.serializer.serialize(node);self.represented_objects={};self.object_keeper=[];self.alias_key=_A
	def represent_data(self,data):
		if self.ignore_aliases(data):self.alias_key=_A
		else:self.alias_key=id(data)
		if self.alias_key is not _A:
			if self.alias_key in self.represented_objects:node=self.represented_objects[self.alias_key];return node
			self.object_keeper.append(data)
		data_types=type(data).__mro__
		if PY2:
			if isinstance(data,types.InstanceType):data_types=get_classobj_bases(data.__class__)+list(data_types)
		if data_types[0]in self.yaml_representers:node=self.yaml_representers[data_types[0]](self,data)
		else:
			for data_type in data_types:
				if data_type in self.yaml_multi_representers:node=self.yaml_multi_representers[data_type](self,data);break
			else:
				if _A in self.yaml_multi_representers:node=self.yaml_multi_representers[_A](self,data)
				elif _A in self.yaml_representers:node=self.yaml_representers[_A](self,data)
				else:node=ScalarNode(_A,text_type(data))
		return node
	def represent_key(self,data):return self.represent_data(data)
	@classmethod
	def add_representer(cls,data_type,representer):
		if'yaml_representers'not in cls.__dict__:cls.yaml_representers=cls.yaml_representers.copy()
		cls.yaml_representers[data_type]=representer
	@classmethod
	def add_multi_representer(cls,data_type,representer):
		if'yaml_multi_representers'not in cls.__dict__:cls.yaml_multi_representers=cls.yaml_multi_representers.copy()
		cls.yaml_multi_representers[data_type]=representer
	def represent_scalar(self,tag,value,style=_A,anchor=_A):
		if style is _A:style=self.default_style
		comment=_A
		if style and style[0]in'|>':
			comment=getattr(value,_F,_A)
			if comment:comment=[_A,[comment]]
		node=ScalarNode(tag,value,style=style,comment=comment,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		return node
	def represent_sequence(self,tag,sequence,flow_style=_A):
		value=[];node=SequenceNode(tag,value,flow_style=flow_style)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		for item in sequence:
			node_item=self.represent_data(item)
			if not(isinstance(node_item,ScalarNode)and not node_item.style):best_style=_C
			value.append(node_item)
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def represent_omap(self,tag,omap,flow_style=_A):
		value=[];node=SequenceNode(tag,value,flow_style=flow_style)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		for item_key in omap:item_val=omap[item_key];node_item=self.represent_data({item_key:item_val});value.append(node_item)
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def represent_mapping(self,tag,mapping,flow_style=_A):
		value=[];node=MappingNode(tag,value,flow_style=flow_style)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		if hasattr(mapping,'items'):
			mapping=list(mapping.items())
			if self.sort_base_mapping_type_on_output:
				try:mapping=sorted(mapping)
				except TypeError:pass
		for (item_key,item_value) in mapping:
			node_key=self.represent_key(item_key);node_value=self.represent_data(item_value)
			if not(isinstance(node_key,ScalarNode)and not node_key.style):best_style=_C
			if not(isinstance(node_value,ScalarNode)and not node_value.style):best_style=_C
			value.append((node_key,node_value))
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def ignore_aliases(self,data):return _C
class SafeRepresenter(BaseRepresenter):
	def ignore_aliases(self,data):
		if data is _A or isinstance(data,tuple)and data==():return _B
		if isinstance(data,(binary_type,text_type,bool,int,float)):return _B
		return _C
	def represent_none(self,data):return self.represent_scalar(_L,_T)
	if PY3:
		def represent_str(self,data):return self.represent_scalar(_D,data)
		def represent_binary(self,data):
			if hasattr(base64,'encodebytes'):data=base64.encodebytes(data).decode(_E)
			else:data=base64.encodestring(data).decode(_E)
			return self.represent_scalar(_M,data,style=_J)
	else:
		def represent_str(self,data):
			tag=_A;style=_A
			try:data=unicode(data,_E);tag=_D
			except UnicodeDecodeError:
				try:data=unicode(data,_U);tag=_D
				except UnicodeDecodeError:data=data.encode(_V);tag=_M;style=_J
			return self.represent_scalar(tag,data,style=style)
		def represent_unicode(self,data):return self.represent_scalar(_D,data)
	def represent_bool(self,data,anchor=_A):
		try:value=self.dumper.boolean_representation[bool(data)]
		except AttributeError:
			if data:value='true'
			else:value='false'
		return self.represent_scalar('tag:yaml.org,2002:bool',value,anchor=anchor)
	def represent_int(self,data):return self.represent_scalar(_G,text_type(data))
	if PY2:
		def represent_long(self,data):return self.represent_scalar(_G,text_type(data))
	inf_value=1e+300
	while repr(inf_value)!=repr(inf_value*inf_value):inf_value*=inf_value
	def represent_float(self,data):
		if data!=data or data==_K and data==1.0:value=_W
		elif data==self.inf_value:value=_X
		elif data==-self.inf_value:value=_Y
		else:
			value=to_unicode(repr(data)).lower()
			if getattr(self.serializer,'use_version',_A)==(1,1):
				if _H not in value and'e'in value:value=value.replace('e','.0e',1)
		return self.represent_scalar(_N,value)
	def represent_list(self,data):return self.represent_sequence(_O,data)
	def represent_dict(self,data):return self.represent_mapping(_P,data)
	def represent_ordereddict(self,data):return self.represent_omap('tag:yaml.org,2002:omap',data)
	def represent_set(self,data):
		value={}
		for key in data:value[key]=_A
		return self.represent_mapping(_Z,value)
	def represent_date(self,data):value=to_unicode(data.isoformat());return self.represent_scalar(_Q,value)
	def represent_datetime(self,data):value=to_unicode(data.isoformat(' '));return self.represent_scalar(_Q,value)
	def represent_yaml_object(self,tag,data,cls,flow_style=_A):
		if hasattr(data,_a):state=data.__getstate__()
		else:state=data.__dict__.copy()
		return self.represent_mapping(tag,state,flow_style=flow_style)
	def represent_undefined(self,data):raise RepresenterError('cannot represent an object: %s'%(data,))
SafeRepresenter.add_representer(type(_A),SafeRepresenter.represent_none)
SafeRepresenter.add_representer(str,SafeRepresenter.represent_str)
if PY2:SafeRepresenter.add_representer(unicode,SafeRepresenter.represent_unicode)
else:SafeRepresenter.add_representer(bytes,SafeRepresenter.represent_binary)
SafeRepresenter.add_representer(bool,SafeRepresenter.represent_bool)
SafeRepresenter.add_representer(int,SafeRepresenter.represent_int)
if PY2:SafeRepresenter.add_representer(long,SafeRepresenter.represent_long)
SafeRepresenter.add_representer(float,SafeRepresenter.represent_float)
SafeRepresenter.add_representer(list,SafeRepresenter.represent_list)
SafeRepresenter.add_representer(tuple,SafeRepresenter.represent_list)
SafeRepresenter.add_representer(dict,SafeRepresenter.represent_dict)
SafeRepresenter.add_representer(set,SafeRepresenter.represent_set)
SafeRepresenter.add_representer(ordereddict,SafeRepresenter.represent_ordereddict)
if sys.version_info>=(2,7):import collections;SafeRepresenter.add_representer(collections.OrderedDict,SafeRepresenter.represent_ordereddict)
SafeRepresenter.add_representer(datetime.date,SafeRepresenter.represent_date)
SafeRepresenter.add_representer(datetime.datetime,SafeRepresenter.represent_datetime)
SafeRepresenter.add_representer(_A,SafeRepresenter.represent_undefined)
class Representer(SafeRepresenter):
	if PY2:
		def represent_str(self,data):
			tag=_A;style=_A
			try:data=unicode(data,_E);tag=_D
			except UnicodeDecodeError:
				try:data=unicode(data,_U);tag='tag:yaml.org,2002:python/str'
				except UnicodeDecodeError:data=data.encode(_V);tag=_M;style=_J
			return self.represent_scalar(tag,data,style=style)
		def represent_unicode(self,data):
			tag=_A
			try:data.encode(_E);tag='tag:yaml.org,2002:python/unicode'
			except UnicodeEncodeError:tag=_D
			return self.represent_scalar(tag,data)
		def represent_long(self,data):
			tag=_G
			if int(data)is not data:tag='tag:yaml.org,2002:python/long'
			return self.represent_scalar(tag,to_unicode(data))
	def represent_complex(self,data):
		if data.imag==_K:data='%r'%data.real
		elif data.real==_K:data='%rj'%data.imag
		elif data.imag>0:data='%r+%rj'%(data.real,data.imag)
		else:data='%r%rj'%(data.real,data.imag)
		return self.represent_scalar('tag:yaml.org,2002:python/complex',data)
	def represent_tuple(self,data):return self.represent_sequence('tag:yaml.org,2002:python/tuple',data)
	def represent_name(self,data):
		try:name=_I%(data.__module__,data.__qualname__)
		except AttributeError:name=_I%(data.__module__,data.__name__)
		return self.represent_scalar('tag:yaml.org,2002:python/name:'+name,'')
	def represent_module(self,data):return self.represent_scalar('tag:yaml.org,2002:python/module:'+data.__name__,'')
	if PY2:
		def represent_instance(self,data):
			cls=data.__class__;class_name=_I%(cls.__module__,cls.__name__);args=_A;state=_A
			if hasattr(data,'__getinitargs__'):args=list(data.__getinitargs__())
			if hasattr(data,_a):state=data.__getstate__()
			else:state=data.__dict__
			if args is _A and isinstance(state,dict):return self.represent_mapping(_b+class_name,state)
			if isinstance(state,dict)and not state:return self.represent_sequence(_R+class_name,args)
			value={}
			if bool(args):value[_c]=args
			value[_d]=state;return self.represent_mapping(_R+class_name,value)
	def represent_object(self,data):
		cls=type(data)
		if cls in copyreg.dispatch_table:reduce=copyreg.dispatch_table[cls](data)
		elif hasattr(data,'__reduce_ex__'):reduce=data.__reduce_ex__(2)
		elif hasattr(data,'__reduce__'):reduce=data.__reduce__()
		else:raise RepresenterError('cannot represent object: %r'%(data,))
		reduce=(list(reduce)+[_A]*5)[:5];function,args,state,listitems,dictitems=reduce;args=list(args)
		if state is _A:state={}
		if listitems is not _A:listitems=list(listitems)
		if dictitems is not _A:dictitems=dict(dictitems)
		if function.__name__=='__newobj__':function=args[0];args=args[1:];tag=_R;newobj=_B
		else:tag='tag:yaml.org,2002:python/object/apply:';newobj=_C
		try:function_name=_I%(function.__module__,function.__qualname__)
		except AttributeError:function_name=_I%(function.__module__,function.__name__)
		if not args and not listitems and not dictitems and isinstance(state,dict)and newobj:return self.represent_mapping(_b+function_name,state)
		if not listitems and not dictitems and isinstance(state,dict)and not state:return self.represent_sequence(tag+function_name,args)
		value={}
		if args:value[_c]=args
		if state or not isinstance(state,dict):value[_d]=state
		if listitems:value['listitems']=listitems
		if dictitems:value['dictitems']=dictitems
		return self.represent_mapping(tag+function_name,value)
if PY2:Representer.add_representer(str,Representer.represent_str);Representer.add_representer(unicode,Representer.represent_unicode);Representer.add_representer(long,Representer.represent_long)
Representer.add_representer(complex,Representer.represent_complex)
Representer.add_representer(tuple,Representer.represent_tuple)
Representer.add_representer(type,Representer.represent_name)
if PY2:Representer.add_representer(types.ClassType,Representer.represent_name)
Representer.add_representer(types.FunctionType,Representer.represent_name)
Representer.add_representer(types.BuiltinFunctionType,Representer.represent_name)
Representer.add_representer(types.ModuleType,Representer.represent_module)
if PY2:Representer.add_multi_representer(types.InstanceType,Representer.represent_instance)
Representer.add_multi_representer(object,Representer.represent_object)
Representer.add_multi_representer(type,Representer.represent_name)
from .comments import CommentedMap,CommentedOrderedMap,CommentedSeq,CommentedKeySeq,CommentedKeyMap,CommentedSet,comment_attrib,merge_attrib,TaggedScalar
class RoundTripRepresenter(SafeRepresenter):
	def __init__(self,default_style=_A,default_flow_style=_A,dumper=_A):
		if not hasattr(dumper,_S)and default_flow_style is _A:default_flow_style=_C
		SafeRepresenter.__init__(self,default_style=default_style,default_flow_style=default_flow_style,dumper=dumper)
	def ignore_aliases(self,data):
		try:
			if data.anchor is not _A and data.anchor.value is not _A:return _C
		except AttributeError:pass
		return SafeRepresenter.ignore_aliases(self,data)
	def represent_none(self,data):
		if len(self.represented_objects)==0 and not self.serializer.use_explicit_start:return self.represent_scalar(_L,_T)
		return self.represent_scalar(_L,'')
	def represent_literal_scalarstring(self,data):
		tag=_A;style=_J;anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	represent_preserved_scalarstring=represent_literal_scalarstring
	def represent_folded_scalarstring(self,data):
		tag=_A;style='>';anchor=data.yaml_anchor(any=_B)
		for fold_pos in reversed(getattr(data,'fold_pos',[])):
			if data[fold_pos]==' 'and(fold_pos>0 and not data[fold_pos-1].isspace())and(fold_pos<len(data)and not data[fold_pos+1].isspace()):data=data[:fold_pos]+'\x07'+data[fold_pos:]
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def represent_single_quoted_scalarstring(self,data):
		tag=_A;style="'";anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def represent_double_quoted_scalarstring(self,data):
		tag=_A;style='"';anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def represent_plain_scalarstring(self,data):
		tag=_A;style='';anchor=data.yaml_anchor(any=_B)
		if PY2 and not isinstance(data,unicode):data=unicode(data,_E)
		tag=_D;return self.represent_scalar(tag,data,style=style,anchor=anchor)
	def insert_underscore(self,prefix,s,underscore,anchor=_A):
		A='_'
		if underscore is _A:return self.represent_scalar(_G,prefix+s,anchor=anchor)
		if underscore[0]:
			sl=list(s);pos=len(s)-underscore[0]
			while pos>0:sl.insert(pos,A);pos-=underscore[0]
			s=''.join(sl)
		if underscore[1]:s=A+s
		if underscore[2]:s+=A
		return self.represent_scalar(_G,prefix+s,anchor=anchor)
	def represent_scalar_int(self,data):
		if data._width is not _A:s='{:0{}d}'.format(data,data._width)
		else:s=format(data,'d')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('',s,data._underscore,anchor=anchor)
	def represent_binary_int(self,data):
		if data._width is not _A:s='{:0{}b}'.format(data,data._width)
		else:s=format(data,'b')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0b',s,data._underscore,anchor=anchor)
	def represent_octal_int(self,data):
		if data._width is not _A:s='{:0{}o}'.format(data,data._width)
		else:s=format(data,'o')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0o',s,data._underscore,anchor=anchor)
	def represent_hex_int(self,data):
		if data._width is not _A:s='{:0{}x}'.format(data,data._width)
		else:s=format(data,'x')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0x',s,data._underscore,anchor=anchor)
	def represent_hex_caps_int(self,data):
		if data._width is not _A:s='{:0{}X}'.format(data,data._width)
		else:s=format(data,'X')
		anchor=data.yaml_anchor(any=_B);return self.insert_underscore('0x',s,data._underscore,anchor=anchor)
	def represent_scalar_float(self,data):
		C='+';B='{:{}0{}d}';A='0';value=_A;anchor=data.yaml_anchor(any=_B)
		if data!=data or data==_K and data==1.0:value=_W
		elif data==self.inf_value:value=_X
		elif data==-self.inf_value:value=_Y
		if value:return self.represent_scalar(_N,value,anchor=anchor)
		if data._exp is _A and data._prec>0 and data._prec==data._width-1:value='{}{:d}.'.format(data._m_sign if data._m_sign else'',abs(int(data)))
		elif data._exp is _A:
			prec=data._prec;ms=data._m_sign if data._m_sign else'';value='{}{:0{}.{}f}'.format(ms,abs(data),data._width-len(ms),data._width-prec-1)
			if prec==0 or prec==1 and ms!='':value=value.replace('0.',_H)
			while len(value)<data._width:value+=A
		else:
			m,es='{:{}.{}e}'.format(data,data._width,data._width+(1 if data._m_sign else 0)).split('e');w=data._width if data._prec>0 else data._width+1
			if data<0:w+=1
			m=m[:w];e=int(es);m1,m2=m.split(_H)
			while len(m1)+len(m2)<data._width-(1 if data._prec>=0 else 0):m2+=A
			if data._m_sign and data>0:m1=C+m1
			esgn=C if data._e_sign else''
			if data._prec<0:
				if m2!=A:e-=len(m2)
				else:m2=''
				while len(m1)+len(m2)-(1 if data._m_sign else 0)<data._width:m2+=A;e-=1
				value=m1+m2+data._exp+B.format(e,esgn,data._e_width)
			elif data._prec==0:e-=len(m2);value=m1+m2+_H+data._exp+B.format(e,esgn,data._e_width)
			else:
				if data._m_lead0>0:m2=A*(data._m_lead0-1)+m1+m2;m1=A;m2=m2[:-data._m_lead0];e+=data._m_lead0
				while len(m1)<data._prec:m1+=m2[0];m2=m2[1:];e-=1
				value=m1+_H+m2+data._exp+B.format(e,esgn,data._e_width)
		if value is _A:value=to_unicode(repr(data)).lower()
		return self.represent_scalar(_N,value,anchor=anchor)
	def represent_sequence(self,tag,sequence,flow_style=_A):
		value=[]
		try:flow_style=sequence.fa.flow_style(flow_style)
		except AttributeError:flow_style=flow_style
		try:anchor=sequence.yaml_anchor()
		except AttributeError:anchor=_A
		node=SequenceNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(sequence,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			item_comments=comment.items;node.comment=comment.comment
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		for (idx,item) in enumerate(sequence):
			node_item=self.represent_data(item);self.merge_comments(node_item,item_comments.get(idx))
			if not(isinstance(node_item,ScalarNode)and not node_item.style):best_style=_C
			value.append(node_item)
		if flow_style is _A:
			if len(sequence)!=0 and self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def merge_comments(self,node,comments):
		if comments is _A:assert hasattr(node,_F);return node
		if getattr(node,_F,_A)is not _A:
			for (idx,val) in enumerate(comments):
				if idx>=len(node.comment):continue
				nc=node.comment[idx]
				if nc is not _A:assert val is _A or val==nc;comments[idx]=nc
		node.comment=comments;return node
	def represent_key(self,data):
		if isinstance(data,CommentedKeySeq):self.alias_key=_A;return self.represent_sequence(_O,data,flow_style=_B)
		if isinstance(data,CommentedKeyMap):self.alias_key=_A;return self.represent_mapping(_P,data,flow_style=_B)
		return SafeRepresenter.represent_key(self,data)
	def represent_mapping(self,tag,mapping,flow_style=_A):
		value=[]
		try:flow_style=mapping.fa.flow_style(flow_style)
		except AttributeError:flow_style=flow_style
		try:anchor=mapping.yaml_anchor()
		except AttributeError:anchor=_A
		node=MappingNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(mapping,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		merge_list=[m[1]for m in getattr(mapping,merge_attrib,[])]
		try:merge_pos=getattr(mapping,merge_attrib,[[0]])[0][0]
		except IndexError:merge_pos=0
		item_count=0
		if bool(merge_list):items=mapping.non_merged_items()
		else:items=mapping.items()
		for (item_key,item_value) in items:
			item_count+=1;node_key=self.represent_key(item_key);node_value=self.represent_data(item_value);item_comment=item_comments.get(item_key)
			if item_comment:
				assert getattr(node_key,_F,_A)is _A;node_key.comment=item_comment[:2];nvc=getattr(node_value,_F,_A)
				if nvc is not _A:nvc[0]=item_comment[2];nvc[1]=item_comment[3]
				else:node_value.comment=item_comment[2:]
			if not(isinstance(node_key,ScalarNode)and not node_key.style):best_style=_C
			if not(isinstance(node_value,ScalarNode)and not node_value.style):best_style=_C
			value.append((node_key,node_value))
		if flow_style is _A:
			if(item_count!=0 or bool(merge_list))and self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		if bool(merge_list):
			if len(merge_list)==1:arg=self.represent_data(merge_list[0])
			else:arg=self.represent_data(merge_list);arg.flow_style=_B
			value.insert(merge_pos,(ScalarNode('tag:yaml.org,2002:merge','<<'),arg))
		return node
	def represent_omap(self,tag,omap,flow_style=_A):
		value=[]
		try:flow_style=omap.fa.flow_style(flow_style)
		except AttributeError:flow_style=flow_style
		try:anchor=omap.yaml_anchor()
		except AttributeError:anchor=_A
		node=SequenceNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(omap,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		for item_key in omap:
			item_val=omap[item_key];node_item=self.represent_data({item_key:item_val});item_comment=item_comments.get(item_key)
			if item_comment:
				if item_comment[1]:node_item.comment=[_A,item_comment[1]]
				assert getattr(node_item.value[0][0],_F,_A)is _A;node_item.value[0][0].comment=[item_comment[0],_A];nvc=getattr(node_item.value[0][1],_F,_A)
				if nvc is not _A:nvc[0]=item_comment[2];nvc[1]=item_comment[3]
				else:node_item.value[0][1].comment=item_comment[2:]
			value.append(node_item)
		if flow_style is _A:
			if self.default_flow_style is not _A:node.flow_style=self.default_flow_style
			else:node.flow_style=best_style
		return node
	def represent_set(self,setting):
		flow_style=_C;tag=_Z;value=[];flow_style=setting.fa.flow_style(flow_style)
		try:anchor=setting.yaml_anchor()
		except AttributeError:anchor=_A
		node=MappingNode(tag,value,flow_style=flow_style,anchor=anchor)
		if self.alias_key is not _A:self.represented_objects[self.alias_key]=node
		best_style=_B
		try:
			comment=getattr(setting,comment_attrib);node.comment=comment.comment
			if node.comment and node.comment[1]:
				for ct in node.comment[1]:ct.reset()
			item_comments=comment.items
			for v in item_comments.values():
				if v and v[1]:
					for ct in v[1]:ct.reset()
			try:node.comment.append(comment.end)
			except AttributeError:pass
		except AttributeError:item_comments={}
		for item_key in setting.odict:
			node_key=self.represent_key(item_key);node_value=self.represent_data(_A);item_comment=item_comments.get(item_key)
			if item_comment:assert getattr(node_key,_F,_A)is _A;node_key.comment=item_comment[:2]
			node_key.style=node_value.style='?'
			if not(isinstance(node_key,ScalarNode)and not node_key.style):best_style=_C
			if not(isinstance(node_value,ScalarNode)and not node_value.style):best_style=_C
			value.append((node_key,node_value))
		best_style=best_style;return node
	def represent_dict(self,data):
		try:t=data.tag.value
		except AttributeError:t=_A
		if t:
			if t.startswith('!!'):tag=_e+t[2:]
			else:tag=t
		else:tag=_P
		return self.represent_mapping(tag,data)
	def represent_list(self,data):
		try:t=data.tag.value
		except AttributeError:t=_A
		if t:
			if t.startswith('!!'):tag=_e+t[2:]
			else:tag=t
		else:tag=_O
		return self.represent_sequence(tag,data)
	def represent_datetime(self,data):
		B='tz';A='delta';inter='T'if data._yaml['t']else' ';_yaml=data._yaml
		if _yaml[A]:data+=_yaml[A];value=data.isoformat(inter)
		else:value=data.isoformat(inter)
		if _yaml[B]:value+=_yaml[B]
		return self.represent_scalar(_Q,to_unicode(value))
	def represent_tagged_scalar(self,data):
		try:tag=data.tag.value
		except AttributeError:tag=_A
		try:anchor=data.yaml_anchor()
		except AttributeError:anchor=_A
		return self.represent_scalar(tag,data.value,style=data.style,anchor=anchor)
	def represent_scalar_bool(self,data):
		try:anchor=data.yaml_anchor()
		except AttributeError:anchor=_A
		return SafeRepresenter.represent_bool(self,data,anchor=anchor)
RoundTripRepresenter.add_representer(type(_A),RoundTripRepresenter.represent_none)
RoundTripRepresenter.add_representer(LiteralScalarString,RoundTripRepresenter.represent_literal_scalarstring)
RoundTripRepresenter.add_representer(FoldedScalarString,RoundTripRepresenter.represent_folded_scalarstring)
RoundTripRepresenter.add_representer(SingleQuotedScalarString,RoundTripRepresenter.represent_single_quoted_scalarstring)
RoundTripRepresenter.add_representer(DoubleQuotedScalarString,RoundTripRepresenter.represent_double_quoted_scalarstring)
RoundTripRepresenter.add_representer(PlainScalarString,RoundTripRepresenter.represent_plain_scalarstring)
RoundTripRepresenter.add_representer(ScalarInt,RoundTripRepresenter.represent_scalar_int)
RoundTripRepresenter.add_representer(BinaryInt,RoundTripRepresenter.represent_binary_int)
RoundTripRepresenter.add_representer(OctalInt,RoundTripRepresenter.represent_octal_int)
RoundTripRepresenter.add_representer(HexInt,RoundTripRepresenter.represent_hex_int)
RoundTripRepresenter.add_representer(HexCapsInt,RoundTripRepresenter.represent_hex_caps_int)
RoundTripRepresenter.add_representer(ScalarFloat,RoundTripRepresenter.represent_scalar_float)
RoundTripRepresenter.add_representer(ScalarBoolean,RoundTripRepresenter.represent_scalar_bool)
RoundTripRepresenter.add_representer(CommentedSeq,RoundTripRepresenter.represent_list)
RoundTripRepresenter.add_representer(CommentedMap,RoundTripRepresenter.represent_dict)
RoundTripRepresenter.add_representer(CommentedOrderedMap,RoundTripRepresenter.represent_ordereddict)
if sys.version_info>=(2,7):import collections;RoundTripRepresenter.add_representer(collections.OrderedDict,RoundTripRepresenter.represent_ordereddict)
RoundTripRepresenter.add_representer(CommentedSet,RoundTripRepresenter.represent_set)
RoundTripRepresenter.add_representer(TaggedScalar,RoundTripRepresenter.represent_tagged_scalar)
RoundTripRepresenter.add_representer(TimeStamp,RoundTripRepresenter.represent_datetime)