U
    /eF                  	   @  s  d Z ddlmZ ddlZeeZddlZddlZddl	Z	ddl
mZ ddlmZmZ ddlmZ ddlmZmZmZmZmZmZ ddlmZ erdd	lmZ d
dlmZ d
dlmZ d
dl m!Z! d
dl"m#Z#m$Z$ ddl%m&Z& erd
dl'm(Z( d
dl)m*Z* dZ+ddddddddddddddddZ,ddddddddddddddd d!Z-dddddddd"ddddddd#d$Z.dde#ddd%dddd&ddd'd(d)d*Z/dde#ddd%dddd&dddd(d+d,Z0dde#ddd%dddd&dddd(d-d.Z1e#ddd/dd&dddd0d1d2Z2d3dd4d5d6d7Z3ed8ddd9d:d;d<Z4ddddd=d>d?Z5d3d4d@dAdBZ6d3dCdDdEdFZ7dGZ8dHZ9dIZ:G dJdK dKZ;dKdLdMdNZ<dS )Oz

    )annotationsN)contextmanager)abspathsplitext)mkstemp)TYPE_CHECKINGAnyIteratorListTuplecast)Image)	WebDriver   )PathLike)Document	file_html)INLINE	Resources   )default_filename)	LayoutDOMPlot)
export_png
export_svgexport_svgsget_layout_htmlget_screenshot_as_pngget_svgs   )filenamewidthheight	webdrivertimeoutzLayoutDOM | DocumentzPathLike | Nonez
int | NonezWebDriver | Noneintstr)objr"   r#   r$   r%   r&   returnc                C  sZ   t | ||||d}|dkr"td}|jdks6|jdkr>tdt|}|| t|S )a   Export the ``LayoutDOM`` object or document as a PNG.

    If the filename is not given, it is derived from the script name (e.g.
    ``/foo/myplot.py`` will create ``/foo/myplot.png``)

    Args:
        obj (LayoutDOM or Document) : a Layout (Row/Column), Plot or Widget
            object or Document to export.

        filename (PathLike, e.g. str, Path, optional) : filename to save document under (default: None)
            If None, infer from the filename.

        width (int) : the desired width of the exported layout obj only if
            it's a Plot instance. Otherwise the width kwarg is ignored.

        height (int) : the desired height of the exported layout obj only if
            it's a Plot instance. Otherwise the height kwarg is ignored.

        webdriver (selenium.webdriver) : a selenium webdriver instance to use
            to export the image.

        timeout (int) : the maximum amount of time (in seconds) to wait for
            Bokeh to initialize (default: 5) (Added in 1.1.1).

    Returns:
        filename (str) : the filename where the static file is saved.

    If you would like to access an Image object directly, rather than save a
    file to disk, use the lower-level :func:`~bokeh.io.export.get_screenshot_as_png`
    function.

    .. warning::
        Responsive sizing_modes may generate layouts with unexpected size and
        aspect ratios. It is recommended to use the default ``fixed`` sizing mode.

    r#   r$   driverr&   Npngr   zunable to save an empty image)	r   r   r#   r$   
ValueErrorosfspathsaver   )r)   r"   r#   r$   r%   r&   image r3   3/tmp/pip-unpacked-wheel-f5fndrjf/bokeh/io/export.pyr   I   s    &

r   z	List[str]c                C  s   t | ||||d}t||dS )a   Export a layout as SVG file or a document as a set of SVG files.

    If the filename is not given, it is derived from the script name
    (e.g. ``/foo/myplot.py`` will create ``/foo/myplot.svg``)

    Args:
        obj (LayoutDOM object) : a Layout (Row/Column), Plot or Widget object to display

        filename (PathLike, e.g. str, Path, optional) : filename to save document under (default: None)
            If None, infer from the filename.

        width (int) : the desired width of the exported layout obj only if
            it's a Plot instance. Otherwise the width kwarg is ignored.

        height (int) : the desired height of the exported layout obj only if
            it's a Plot instance. Otherwise the height kwarg is ignored.

        webdriver (selenium.webdriver) : a selenium webdriver instance to use
            to export the image.

        timeout (int) : the maximum amount of time (in seconds) to wait for
            Bokeh to initialize (default: 5)

    Returns:
        filenames (list(str)) : the list of filenames where the SVGs files are saved.

    .. warning::
        Responsive sizing_modes may generate layouts with unexpected size and
        aspect ratios. It is recommended to use the default ``fixed`` sizing mode.

    r+   svg)get_svg_write_collectionr)   r"   r#   r$   r%   r&   svgsr3   r3   r4   r   |   s    !r   z
str | Nonec                C  s8   t | ||||d}t|dkr,td g S t||dS )a   Export the SVG-enabled plots within a layout. Each plot will result
    in a distinct SVG file.

    If the filename is not given, it is derived from the script name
    (e.g. ``/foo/myplot.py`` will create ``/foo/myplot.svg``)

    Args:
        obj (LayoutDOM object) : a Layout (Row/Column), Plot or Widget object to display

        filename (str, optional) : filename to save document under (default: None)
            If None, infer from the filename.

        width (int) : the desired width of the exported layout obj only if
            it's a Plot instance. Otherwise the width kwarg is ignored.

        height (int) : the desired height of the exported layout obj only if
            it's a Plot instance. Otherwise the height kwarg is ignored.

        webdriver (selenium.webdriver) : a selenium webdriver instance to use
            to export the image.

        timeout (int) : the maximum amount of time (in seconds) to wait for
            Bokeh to initialize (default: 5) (Added in 1.1.1).

    Returns:
        filenames (list(str)) : the list of filenames where the SVGs files are saved.

    .. warning::
        Responsive sizing_modes may generate layouts with unexpected size and
        aspect ratios. It is recommended to use the default ``fixed`` sizing mode.

    r+   r   zNo SVG Plots were found.r5   )r    lenlogwarningr7   r8   r3   r3   r4   r      s
    "
r   )r,   r&   	resourcesr#   r$   r   zImage.Image)r)   r,   r&   r=   r#   r$   r*   c             
   C  s   ddl m} t }t| |||d}t|jddd}	|	| W 5 Q R X |dk	rV|n| }
|
  |
d|j  t	|
| t
|
\}}}|
 }W 5 Q R X tt|d	d
d
|| || f||fS )a   Get a screenshot of a ``LayoutDOM`` object.

    Args:
        obj (LayoutDOM or Document) : a Layout (Row/Column), Plot or Widget
            object or Document to export.

        driver (selenium.webdriver) : a selenium webdriver instance to use
            to export the image.

        timeout (int) : the maximum amount of time to wait for initialization.
            It will be used as a timeout for loading Bokeh, then when waiting for
            the layout to be rendered.

    Returns:
        image (PIL.Image.Image) : a pillow image loaded from PNG.

    .. warning::
        Responsive sizing_modes may generate layouts with unexpected size and
        aspect ratios. It is recommended to use the default ``fixed`` sizing mode.

    r   webdriver_controlr=   r#   r$   wutf-8modeencodingNfile://ZRGBAr   )r%   r?   	_tmp_htmlr   openpathwritegetZmaximize_windowwait_until_render_complete_maximize_viewportr   r   ioBytesIOconvertZcropresize)r)   r,   r&   r=   r#   r$   r?   tmphtmlfile
web_driverZdprr-   r3   r3   r4   r      s$    
r   c             
   C  s   ddl m} t }t| |||d}t|jddd}	|	| W 5 Q R X |d k	rV|n| }
|
d|j  t|
| t	t
t |
t}W 5 Q R X |S Nr   r>   r@   rA   rB   rC   rF   )r%   r?   rG   r   rH   rI   rJ   rK   rL   r   r
   r(   execute_script_SVG_SCRIPTr)   r,   r&   r=   r#   r$   r?   rR   rS   rT   rU   r9   r3   r3   r4   r6      s    
r6   c             
   C  s   ddl m} t }t| |||d}t|jddd}	|	| W 5 Q R X |d k	rV|n| }
|
d|j  t|
| t	t
t |
t}W 5 Q R X |S rV   )r%   r?   rG   r   rH   rI   rJ   rK   rL   r   r
   r(   rW   _SVGS_SCRIPTrY   r3   r3   r4   r      s    
r    r@   )r)   r=   r#   r$   r*   c             
     sx   ddd fdd}|dk	s*|dk	rrddl m} t |sLtd	 n&t || | W  5 Q R  S Q R X | S )


    a%  \
    {% block preamble %}
    <style>
        html, body {
            box-sizing: border-box;
            width: 100%;
            height: 100%;
            margin: 0;
            border: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
    {% endblock %}
    r(   r*   c                     s   t  ddddS )N T)titletemplateZsuppress_callback_warningZ_always_newr   r3   r)   r=   r_   r3   r4   rS   -  s    zget_layout_html.<locals>.htmlNr   r   zhExport method called with width or height argument on a non-Plot model. The size values will be ignored.)models.plotsr   
isinstancewarningswarn_resized)r)   r=   r#   r$   rS   r   r3   r`   r4   r     s    
r   r   None)r,   r&   r*   c              
   C  s   ddl m} ddlm} ddddd}z|| |d	d
| W n4 |k
rt } zt|  td|W 5 d}~X Y nX | t ddddd}z<z|| |d	d
| W n |k
r   t	
d Y nX W 5 t|  X dS )r[   r   )TimeoutException)WebDriverWaitr   boolr,   r*   c                 S  s   t t| dS )Nzs
            return typeof Bokeh !== "undefined" && Bokeh.documents != null && Bokeh.documents.length != 0
        r   ri   rW   r,   r3   r3   r4   is_bokeh_loadedB  s    z3wait_until_render_complete.<locals>.is_bokeh_loadedg?)Zpoll_frequencyz<Bokeh was not loaded in time. Something may have gone wrong.Nc                 S  s   t t| dS )Nz%return window._bokeh_render_complete;rk   rl   r3   r3   r4   is_bokeh_render_completeO  s    z<wait_until_render_complete.<locals>.is_bokeh_render_completezThe webdriver raised a TimeoutException while waiting for a 'bokeh:idle' event to signify that the layout has rendered. Something may have gone wrong.)Zselenium.common.exceptionsrg   Zselenium.webdriver.support.waitrh   Zuntil_log_consoleRuntimeErrorrW   _WAIT_SCRIPTr;   r<   )r,   r&   rg   rh   rm   ern   r3   r3   r4   rL   ;  s    
rL   r   zIterator[None])r)   r#   r$   r*   c                 c  s>   | j }| j}|d k	r|| _ |d k	r(|| _d V  || _ || _d S N)r#   r$   )r)   r#   r$   Z	old_widthZ
old_heightr3   r3   r4   re   _  s    re   )itemsr"   extr*   c           	   
   C  s   |d krt |}t|}g }dddddd}t| D ]L\}}|dkrL|n|||}t|ddd	}|| W 5 Q R X || q8|S )
Nr(   r'   )nameir*   c                 S  s   t | \}}| d| | S )N_)r   )rv   rw   basenameru   r3   r3   r4   _indexedu  s    z#_write_collection.<locals>._indexedr   rA   rB   rC   )r   r/   r0   	enumeraterH   rJ   append)	rt   r"   ru   	filenamesrz   rw   itemfnamefr3   r3   r4   r7   n  s    
r7   rj   c                   sp   dddh z|  d}W n tk
r.   Y d S X  fdd|D }t|dkrltd |D ]}t| q\d S )	NWARNINGERRORZSEVEREZbrowserc                   s$   g | ]}| d  kr| dqS )levelmessage)rK   ).0r;   levelsr3   r4   
<listcomp>  s      z _log_console.<locals>.<listcomp>r   zLThere were browser warnings and/or errors that may have affected your export)Zget_log	Exceptionr:   r;   r<   )r,   Zlogsmessagesr   r3   r   r4   ro     s    

ro   zTuple[int, int, int])rU   r*   c                 C  sB   d}|  |}d}| j |f| \}}d}| || ||  |S )Nz        const root = document.getElementsByClassName("bk-root")[0]
        const {width, height} = root.children[0].getBoundingClientRect()
        return [width, height, window.devicePixelRatio]
    aI          const [width, height, dpr] = arguments
        return [
            // XXX: outer{Width,Height} can be 0 in headless mode under certain window managers
            Math.max(0, window.outerWidth - window.innerWidth) + width*dpr,
            Math.max(0, window.outerHeight - window.innerHeight) + height*dpr,
        ]
    d   )rW   Zset_window_size)rU   Zcalculate_viewport_sizeZviewport_sizeZcalculate_window_sizer#   r$   Zepsr3   r3   r4   rM     s    
rM   a  
const {LayoutDOMView} = Bokeh.require("models/layouts/layout_dom")
const {PlotView} = Bokeh.require("models/plots/plot")

function* collect_svgs(views) {
  for (const view of views) {
    if (view instanceof LayoutDOMView) {
      yield* collect_svgs(view.child_views.values())
    }
    if (view instanceof PlotView && view.model.output_backend == "svg") {
      const {ctx} = view.canvas_view.compose()
      yield ctx.get_serialized_svg(true)
    }
  }
}

const root_views = Object.values(Bokeh.index)
return [...collect_svgs(root_views)]
a  function* export_svgs(views) {
  for (const view of views) {
    // TODO: use to_blob() API in future
    const {ctx} = view.export("svg")
    yield ctx.get_serialized_svg(true)
  }
}

const root_views = Object.values(Bokeh.index)
return [...export_svgs(root_views)]
z
// add private window prop to check that render is complete
window._bokeh_render_complete = false;
function done() {
  window._bokeh_render_complete = true;
}

const doc = Bokeh.documents[0];

if (doc.is_idle)
  done();
else
  doc.idle.connect(done);
c                   @  s   e Zd ZU dZded< ded< ded< dd	d
ddddddZd dddZdddddddZddddZddddZ	dS )	_TempFileFri   _closedr'   fdr(   rI   rR   r]   prefixsuffixrf   )r   r   r*   c             	   C  sP   zt ||t d\| _| _W n, ttfk
rJ   t ||d\| _| _Y nX d S )N)r   r   dirr   )r   r/   getcwdr   rI   OSErrorIOError)selfr   r   r3   r3   r4   __init__  s    z_TempFile.__init__r\   c                 C  s   | S rs   r3   r   r3   r3   r4   	__enter__  s    z_TempFile.__enter__r   )excvaluetbr*   c                 C  s   |    d S rs   close)r   r   r   r   r3   r3   r4   __exit__  s    z_TempFile.__exit__c                 C  s   |    d S rs   r   r   r3   r3   r4   __del__  s    z_TempFile.__del__c                 C  s`   | j r
d S zt| j W n tk
r.   Y nX zt| j W n tk
rT   Y nX d| _ d S )NT)r   r/   r   r   r   unlinkrI   r   r3   r3   r4   r     s    z_TempFile.closeN)
__name__
__module____qualname__r   __annotations__r   r   r   r   r   r3   r3   r3   r4   r     s   
	r   r\   c                   C  s   t dddS )NZbokehz.htmlr   )r   r3   r3   r3   r4   rG     s    rG   )=__doc__
__future__r   logging	getLoggerr   r;   rN   r/   rc   
contextlibr   os.pathr   r   tempfiler   typingr   r   r	   r
   r   r   ZPILr   Z#selenium.webdriver.remote.webdriverr   Z
core.typesr   documentr   embedr   r=   r   r   utilr   Zmodels.layoutsr   ra   r   __all__r   r   r   r   r6   r    r   rL   re   r7   ro   rM   rZ   rX   rq   r   rG   r3   r3   r3   r4   <module>   s   
 
  3  $  .  *     #$(