Problems combining members with different runtime

I have had some trouble reading the 'IPSL' model with intake esm locally ( on the Princeton Server tigressdata). When I am attempting to read all available o2 data for the ssp585 scenario.
# First find all models with *any* o2 data on tigress
url = "/tigress/GEOCLIM/LRGROUP/jbusecke/code/intake-esm-datastore/catalogs/tigressdata-cmip6.json"
col = intake.open_esm_datastore(url)
cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585')#, member_id='r1i1p1f1'
ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': False,})

This throws an error:

distributed.worker - WARNING -  Compute Failed
Function:  execute_task
args:      ((, (, ['ScenarioMIP', 'IPSL', 'IPSL-CM6A-LR', 'ssp585', 'Omon', 'gn']),    activity_id institution_id     source_id experiment_id  member_id table_id  \
0  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585  r14i1p1f1     Omon
1  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r1i1p1f1     Omon
2  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r1i1p1f1     Omon
3  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r1i1p1f1     Omon
4  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r1i1p1f1     Omon
5  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r2i1p1f1     Omon
6  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r3i1p1f1     Omon
7  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r4i1p1f1     Omon
8  ScenarioMIP           IPSL  IPSL-CM6A-LR        ssp585   r6i1p1f1     Omon
variable_id grid_label  dcpp_init_year    version
kwargs:    {}
Exception: ValueError("cannot reindex or align along dimension 'time' because the index has duplicate values")

ValueError                Traceback (most recent call last)
 in
4 col = intake.open_esm_datastore(url)
5 cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585')#, member_id='r1i1p1f1'
----> 6 ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': False,})# YUP this fails, when choosing all member_ids
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/core.py in to_dataset_dict(self, zarr_kwargs, cdf_kwargs, preprocess, aggregate, storage_options, progressbar)
378             self.progressbar = progressbar
379
--> 380         return self._open_dataset()
381
382     def _open_dataset(self):
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/core.py in _open_dataset(self)
472             )
473
--> 474         dsets = client.gather(futures)
475         self._ds = {group_id: ds for (group_id, ds) in dsets}
476
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/distributed/client.py in gather(self, futures, errors, direct, asynchronous)
1886             else:
1887                 local_worker = None
-> 1888             return self.sync(
1889                 self._gather,
1890                 futures,
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/distributed/client.py in sync(self, func, asynchronous, callback_timeout, *args, **kwargs)
775             return future
776         else:
--> 777             return sync(
778                 self.loop, func, *args, callback_timeout=callback_timeout, **kwargs
779             )
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/distributed/utils.py in sync(loop, func, callback_timeout, *args, **kwargs)
346     if error[0]:
347         typ, exc, tb = error[0]
--> 348         raise exc.with_traceback(tb)
349     else:
350         return result[0]
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/distributed/utils.py in f()
330             if callback_timeout is not None:
331                 future = asyncio.wait_for(future, callback_timeout)
--> 332             result[0] = yield future
333         except Exception as exc:
334             error[0] = sys.exc_info()
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/tornado/gen.py in run(self)
733
734                     try:
--> 735                         value = future.result()
736                     except Exception:
737                         exc_info = sys.exc_info()
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/distributed/client.py in _gather(self, futures, errors, direct, local_worker)
1751                             exc = CancelledError(key)
1752                         else:
-> 1753                             raise exception.with_traceback(traceback)
1754                         raise exc
1755                     if errors == "skip":
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/core.py in _load_group_dataset(key, df, col_data, agg_columns, aggregation_dict, path_column_name, variable_column_name, use_format_column, mapper_dict, zarr_kwargs, cdf_kwargs, preprocess)
549         )
550
--> 551     ds = _aggregate(
552         aggregation_dict,
553         agg_columns,
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/merge_util.py in _aggregate(aggregation_dict, agg_columns, n_agg, v, lookup, mapper_dict, zarr_kwargs, cdf_kwargs, preprocess)
174             return ds
175
--> 176     return apply_aggregation(v)
177
178
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/merge_util.py in apply_aggregation(v, agg_column, key, level)
119                 agg_options = {}
120
--> 121             dsets = [
122                 apply_aggregation(value, agg_column, key=key, level=level + 1)
123                 for key, value in v.items()
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/merge_util.py in (.0)
120
121             dsets = [
--> 122                 apply_aggregation(value, agg_column, key=key, level=level + 1)
123                 for key, value in v.items()
124             ]
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/merge_util.py in apply_aggregation(v, agg_column, key, level)
147                 )
148                 varname = dsets[0].attrs['intake_esm_varname']
--> 149                 ds = join_new(
150                     dsets,
151                     dim_name=agg_column,
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/merge_util.py in join_new(dsets, dim_name, coord_value, varname, options)
23     except Exception as e:
24         logger.error(f'Failed to join datasets along new dimension.')
---> 25         raise e
26
27
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/intake_esm/merge_util.py in join_new(dsets, dim_name, coord_value, varname, options)
20     try:
21         concat_dim = xr.DataArray(coord_value, dims=(dim_name), name=dim_name)
---> 22         return xr.concat(dsets, dim=concat_dim, data_vars=varname, **options)
23     except Exception as e:
24         logger.error(f'Failed to join datasets along new dimension.')
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/core/concat.py in concat(objs, dim, data_vars, coords, compat, positions, fill_value, join)
133             "objects, got %s" % type(first_obj)
134         )
--> 135     return f(objs, dim, data_vars, coords, compat, positions, fill_value, join)
136
137
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/core/concat.py in _dataset_concat(datasets, dim, data_vars, coords, compat, positions, fill_value, join)
316     # Make sure we're working on a copy (we'll be loading variables)
317     datasets = [ds.copy() for ds in datasets]
--> 318     datasets = align(
319         *datasets, join=join, copy=False, exclude=[dim], fill_value=fill_value
320     )
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/core/alignment.py in align(join, copy, indexes, exclude, fill_value, *objects)
335             new_obj = obj.copy(deep=copy)
336         else:
--> 337             new_obj = obj.reindex(copy=copy, fill_value=fill_value, **valid_indexers)
338         new_obj.encoding = obj.encoding
339         result.append(new_obj)
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/core/dataset.py in reindex(self, indexers, method, tolerance, copy, fill_value, **indexers_kwargs)
2488
2489         """
-> 2490         return self._reindex(
2491             indexers,
2492             method,
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/core/dataset.py in _reindex(self, indexers, method, tolerance, copy, fill_value, sparse, **indexers_kwargs)
2517             raise ValueError("invalid reindex dimensions: %s" % bad_dims)
2518
-> 2519         variables, indexes = alignment.reindex_variables(
2520             self.variables,
2521             self.sizes,
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/core/alignment.py in reindex_variables(variables, sizes, indexes, indexers, method, tolerance, copy, fill_value, sparse)
545
546             if not index.is_unique:
--> 547                 raise ValueError(
548                     "cannot reindex or align along dimension %r because the "
549                     "index has duplicate values" % dim
ValueError: cannot reindex or align along dimension 'time' because the index has duplicate values

I think the problem is that one of the members (r1i1p1f1) has a longer runtime than the others.
If you only load that member it works:
cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585',member_id='r1i1p1f1')
ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': True,})
ddict

{'ScenarioMIP.IPSL.IPSL-CM6A-LR.ssp585.Omon.gn': <xarray.Dataset>
 Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 3432, x: 362, y: 332)
 Coordinates:
     nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
     nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
   * time            (time) object 2015-01-16T12:00:00 ... 2300-12-16 12:00:00
   * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
   * member_id       (member_id) <U8 'r1i1p1f1'
 Dimensions without coordinates: axis_nbounds, nvertex, x, y
 Data variables:
     bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
     bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
     time_bounds     (time, axis_nbounds) object dask.array<chunksize=(6, 2), meta=np.ndarray>
     olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
     area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
     o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>

But you can also see that it has 3000+ timesteps (running till 2300).
For comparison, other members only have ~1000 timesteps (standard time until 2100):
cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585',member_id='r2i1p1f1')#,
ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': True,})# YUP this fails, when choosing all member_ids
ddict

{'ScenarioMIP.IPSL.IPSL-CM6A-LR.ssp585.Omon.gn': <xarray.Dataset>
 Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 1032, x: 362, y: 332)
 Coordinates:
     nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
     nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
   * time            (time) datetime64[ns] 2015-01-16T12:00:00 ... 2100-12-16T12:00:00
   * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
   * member_id       (member_id) <U8 'r2i1p1f1'
 Dimensions without coordinates: axis_nbounds, nvertex, x, y
 Data variables:
     bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
     bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
     time_bounds     (time, axis_nbounds) datetime64[ns] dask.array<chunksize=(6, 2), meta=np.ndarray>
     olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
     area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
     o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>

It seems that intake-esm struggles with merging those datasets. In the cloud storage the extended member was removed, so the initial call works (cc @naomi-henderson). But I would be really interested in using these extended data.
Is there a way to make this work? I thought it might be possible to alter the attrs of the data sets with preprocessing, but had no luck in getting this to work. I think in principle these are mislabelled and should be a separate experiment ssp585-extended or similar.
Any suggestions for solving this?

Is there a way to make this work?

Yes, this is doable. This seems to be related to the time alignment issue in https://github.com/NCAR/intake-esm/issues/197. Earlier versions of intake-esm (prior v2019.10) used to do time alignment for use cases in which one ensemble member had extended time axis. If nobody beats me to it, I will look into this in the coming weeks (starting by next week).

Any suggestions for solving this?

Here's the code that did time alignment in earlier versions of intake-esm:
https://github.com/NCAR/intake-esm/blob/b9298567f806d429d630fecc46d352c9ec782a02/intake_esm/aggregate.py#L242-L262
Cc @dcherian in case he has suggestions on how to address this issue.

One of those datasets has duplicate time values. Fix that and things should work.

@dcherian, that was my first thought too, but I was not able to find duplicate times, when loading each file individually, so I assumed the duplicates are created internally somehow? I will check again carefully...

Did you use ds.indexes["time"].is_unique to check?

Oh no. I just compared len(ds.time) and len(np.unique(ds.time.data)) and they are the same lenght. Let me check with your method...

Yes I can confirm that each dataset has unique time values. So presumable something inside intake-esm causes a duplication?
I also checked if I can read all other members (except the long one), and that works perfectly fine.

I guess it could be a different dimension

Or not. The error says "time" hmm

I'm just learning intake-esm so forgive me if this question is misdirected, but I was looking at your query results and I noticed something that doesn't match up.  I looked up the available o2 files from IPSL on ESGF for ssp585 (https://esgf-node.llnl.gov/search/cmip6/?source_id=IPSL-CM6A-LR&variable_id=o2&experiment_id=ssp585) and the results are different.  While ensemble members 14, 2, 3, 4, and 6 all have one file to download (years 2015-2100), ensemble member 1 has 3 files to download (years 2015-2300).  Ensemble member 1 doesn't match because it has 4 query entries listed in your error report:
0 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r14i1p1f1 Omon
1 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r1i1p1f1 Omon
2 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r1i1p1f1 Omon
3 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r1i1p1f1 Omon
4 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r1i1p1f1 Omon
5 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r2i1p1f1 Omon
6 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r3i1p1f1 Omon
7 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r4i1p1f1 Omon
8 ScenarioMIP IPSL IPSL-CM6A-LR ssp585 r6i1p1f1 Omon
Do you have a duplicate file that is being found and this is causing duplicates in the time dimension?  Or is the error within intake-esm?

@sherimickelson yes that is right. It seems that this particular model ran an extended ssp585 scenario for member r1i1p1f1, but I am unable to 'pick that out' with the given functionality in intake-esm.
Ideally I would like intake-esm in this case to concat the members in time first and then merge them (producing missing values for 2100-2300 for all other members...
Another solution would be to somehow not use the extended time (on the pangeo cloud, these files were just removed), but for my specific science application this long run is extremely interesting, so I would love to investigate it!

@jbusecke, what's the output of
cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585')
cat.df['path'].tolist()

???

Also, is the CSV from /tigress/GEOCLIM/LRGROUP/jbusecke/code/intake-esm-datastore/catalogs/tigressdata-cmip6.json publicly accessible?

The output is:
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r14i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r14i1p1f1_gn_201501-210012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190119/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_210101-220012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_220101-230012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r2i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r2i1p1f1_gn_201501-210012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r3i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r3i1p1f1_gn_201501-210012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r4i1p1f1/Omon/o2/gn/v20191122/o2_Omon_IPSL-CM6A-LR_ssp585_r4i1p1f1_gn_201501-210012.nc',
 '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r6i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r6i1p1f1_gn_201501-210012.nc']

The csv is not publicly accessible at the moment, but I could send it to you if that works? Do you need access to the data to debug? Or just the csv?

Check your email for the files.

@jbusecke It looks like your catalog includes both versions of this file
'/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190119/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc',
'/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc',
It looks like that's where the duplication in time is happening.  You might want to make sure it's not using version v20190119 because the other files it that time series are using v20190903.

@sherimickelson, thank you for catching the version issue
@jbusecke, when you built the catalog, did you use the --pick-latest-version flag?
I am asking because it appears that for some files, there's more than one version:

/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190119/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc, ---> version=v20190119
/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc, ---> version=v20190903

Ohh that would make sense I guess. But I did invoke the flag you mentioned. Here is the full command:
python cmip.py --root-path /tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6 --pick-latest-version --cmip-version 6 --csv-filepath ../catalogs/tigressdata-cmip6.csv.gz --depth 4
Should I rebuild the catalog once more?

Should I rebuild the catalog once more?

Not yet. I am looking into the csv you just sent me to make sure that --pick-latest-version flag is working as expected.

@andersy005 Does the latest flag only work on directories called "latest" like we have on glade?  Or does it look and see which version number is higher?  If it only does the first, that could be the issue because neither are in a "latest" directory.  (I can't remember what the code does)

Does the latest flag only work on directories called "latest" like we have on glade? Or does it look and see which version number is higher?

It looks for which version number is higher.
def _pick_latest_version(df):
    import itertools

    grpby = list(set(df.columns.tolist()) - {'path', 'version'})
    groups = df.groupby(grpby)

    @dask.delayed
    def _pick_latest_v(group):
        idx = []
        if group.version.nunique() > 1:
            idx = group.sort_values(by=['version'], ascending=False).index[1:].values.tolist()
        return idx

    idx_to_remove = [_pick_latest_v(group) for _, group in groups]
    print('Getting latest version...\n')
    with ProgressBar():
        idx_to_remove = dask.compute(*idx_to_remove)

    idx_to_remove = list(itertools.chain(*idx_to_remove))
    df = df.drop(index=idx_to_remove)
    print('\nDone....\n')
    return df

Not sure if this is relevant, but if I specify member_id='r1i1p1f1', it still registers the duplicate files:
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190119/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc',
'/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc',
'/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_210101-220012.nc',
'/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_220101-230012.nc']
yet it combines the files without complaining...:
<xarray.Dataset>
Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 3432, x: 362, y: 332)
Coordinates:
    nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
    nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
  * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
  * time            (time) object 2015-01-16T12:00:00 ... 2300-12-16 12:00:00
  * member_id       (member_id) <U8 'r1i1p1f1'
Dimensions without coordinates: axis_nbounds, nvertex, x, y
Data variables:
    olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
    time_bounds     (time, axis_nbounds) object dask.array<chunksize=(6, 2), meta=np.ndarray>
    bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
    bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>
Attributes:
    branch_time_in_parent:  60265.0
    parent_source_id:       IPSL-CM6A-LR
    frequency:              mon
    source_type:            AOGCM BGC
    realm:                  ocnBgchem
    branch_method:          standard
    sub_experiment_id:      none
    parent_variant_label:   r1i1p1f1
    description:            Future scenario with high radiative forcing by th...
    external_variables:     areacello volcello
    history:                none
    sub_experiment:         none
    branch_time_in_child:   0.0
    source:                 IPSL-CM6A-LR (2017):  atmos: LMDZ (NPv6, N96; 144...
    creation_date:          2019-08-22T22:26:32Z
    mip_era:                CMIP6
    intake_esm_varname:     o2
    forcing_index:          1
    name:                   /ccc/work/cont003/gencmip6/oboucher/IGCM_OUT/IPSL...
    grid:                   native ocean tri-polar grid with 105 k ocean cells
    parent_time_units:      days since 1850-01-01 00:00:00
    variable_id:            o2
    license:                CMIP6 model data produced by IPSL is licensed und...
    parent_activity_id:     CMIP
    nominal_resolution:     100 km
    experiment_id:          ssp585
    activity_id:            ScenarioMIP
    parent_mip_era:         CMIP6
    title:                  IPSL-CM6A-LR model output prepared for CMIP6 / Sc...
    product:                model-output
    further_info_url:       https://furtherinfo.es-doc.org/CMIP6.IPSL.IPSL-CM...
    institution_id:         IPSL
    variant_label:          r1i1p1f1
    data_specs_version:     01.00.28
    grid_label:             gn
    realization_index:      1
    tracking_id:            hdl:21.14100/dcd42bc5-cc58-4234-b58e-21e4b624ba04...
    institution:            Institut Pierre Simon Laplace, Paris 75252, France
    initialization_index:   1
    experiment:             update of RCP8.5 based on SSP5
    contact<EMAIL_ADDRESS>    dr2xml_md5sum:          c4b76079137f2c3b9298396d121b21c1
    table_id:               Omon
    source_id:              IPSL-CM6A-LR
    CMIP6_CV_version:       cv=<IP_ADDRESS>
    parent_experiment_id:   historical
    Conventions:            CF-1.7 CMIP-6.2
    physics_index:          1
    dr2xml_version:         1.16
    model_version:          6.1.8
    EXPID:                  ssp585
    variant_info:           Each member starts from the corresponding member ...

It will combine but check .indexes["time"].is_unique of the combined result...

related: https://github.com/pydata/xarray/issues/2108

@jbusecke, as a temporary solution, try the following and see what happens:
url = "/tigress/GEOCLIM/LRGROUP/jbusecke/code/intake-esm-datastore/catalogs/tigressdata-cmip6.json"
col = intake.open_esm_datastore(url)
cat = col.search(source_id="IPSL-CM6A-LR", variable_id="o2", experiment_id="ssp585")
cat.df = cat.df.drop(index=[1]) # Drop the problematic file
ddict = cat.to_dataset_dict(cdf_kwargs={"chunks": {"time": 6}, "decode_times": True,})

@dcherian this is what I did:
members = cat.df['member_id'].unique()
for member in members:
    print(f'#####################{member}##################')
    print(member)
    cat_single = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585',member_id=member)
    ddict = cat_single.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': True,})
    assert len(ddict.keys()) == 1
    _,ds = ddict.popitem()
    print(ds.indexes["time"].is_unique)
    print(f"{len(ds.time)}/{len(np.unique(ds.time.data))}")
    print(cat_single.df['path'].tolist())
    print(ds)

I get:
#####################r14i1p1f1##################
r14i1p1f1

--> The keys in the returned dictionary of datasets are constructed as follows:
	'activity_id.institution_id.source_id.experiment_id.table_id.grid_label'

--> There is/are 1 group(s)
True
1032/1032
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r14i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r14i1p1f1_gn_201501-210012.nc']
<xarray.Dataset>
Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 1032, x: 362, y: 332)
Coordinates:
    nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
    nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
  * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
  * time            (time) datetime64[ns] 2015-01-16T12:00:00 ... 2100-12-16T12:00:00
  * member_id       (member_id) <U9 'r14i1p1f1'
Dimensions without coordinates: axis_nbounds, nvertex, x, y
Data variables:
    olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
    time_bounds     (time, axis_nbounds) datetime64[ns] dask.array<chunksize=(6, 2), meta=np.ndarray>
    bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
    bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>
Attributes:
    name:                   /ccc/work/cont003/gencmip6/oboucher/IGCM_OUT/IPSL...
    Conventions:            CF-1.7 CMIP-6.2
    creation_date:          2019-10-13T08:15:27Z
    tracking_id:            hdl:21.14100/fefe8ea3-d0b3-4828-ba16-b66fad793928
    description:            Future scenario with high radiative forcing by th...
    title:                  IPSL-CM6A-LR model output prepared for CMIP6 / Sc...
    activity_id:            ScenarioMIP
    contact<EMAIL_ADDRESS>    data_specs_version:     01.00.28
    dr2xml_version:         1.16
    experiment_id:          ssp585
    experiment:             update of RCP8.5 based on SSP5
    external_variables:     areacello volcello
    forcing_index:          1
    frequency:              mon
    further_info_url:       https://furtherinfo.es-doc.org/CMIP6.IPSL.IPSL-CM...
    grid:                   native ocean tri-polar grid with 105 k ocean cells
    grid_label:             gn
    nominal_resolution:     100 km
    history:                none
    initialization_index:   1
    institution_id:         IPSL
    institution:            Institut Pierre Simon Laplace, Paris 75252, France
    license:                CMIP6 model data produced by IPSL is licensed und...
    mip_era:                CMIP6
    parent_mip_era:         CMIP6
    parent_source_id:       IPSL-CM6A-LR
    parent_time_units:      days since 1850-01-01 00:00:00
    parent_variant_label:   r14i1p1f1
    branch_method:          standard
    branch_time_in_parent:  60265.0
    branch_time_in_child:   0.0
    physics_index:          1
    product:                model-output
    realization_index:      14
    realm:                  ocnBgchem
    source:                 IPSL-CM6A-LR (2017):  atmos: LMDZ (NPv6, N96; 144...
    source_id:              IPSL-CM6A-LR
    source_type:            AOGCM BGC
    sub_experiment_id:      none
    sub_experiment:         none
    table_id:               Omon
    variable_id:            o2
    variant_info:           Each member starts from the corresponding member ...
    variant_label:          r14i1p1f1
    EXPID:                  ssp585
    CMIP6_CV_version:       cv=<IP_ADDRESS>
    dr2xml_md5sum:          b6f602401512e82e2d7cadc2c6f36c2a
    model_version:          6.1.10
    parent_experiment_id:   historical
    parent_activity_id:     CMIP
    intake_esm_varname:     o2
#####################r1i1p1f1##################
r1i1p1f1

--> The keys in the returned dictionary of datasets are constructed as follows:
	'activity_id.institution_id.source_id.experiment_id.table_id.grid_label'

--> There is/are 1 group(s)

/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/coding/times.py:426: SerializationWarning: Unable to decode time axis into full numpy.datetime64 objects, continuing using cftime.datetime objects instead, reason: dates out of range
  dtype = _decode_cf_datetime_dtype(data, units, calendar, self.use_cftime)
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/xarray/coding/times.py:426: SerializationWarning: Unable to decode time axis into full numpy.datetime64 objects, continuing using cftime.datetime objects instead, reason: dates out of range
  dtype = _decode_cf_datetime_dtype(data, units, calendar, self.use_cftime)
/tigress/jbusecke/code/conda/envs/euc_dynamics/lib/python3.8/site-packages/numpy/core/_asarray.py:85: SerializationWarning: Unable to decode time axis into full numpy.datetime64 objects, continuing using cftime.datetime objects instead, reason: dates out of range
  return array(a, dtype, copy=False, order=order)

True
3432/3432
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190119/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc', '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_201501-210012.nc', '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_210101-220012.nc', '/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r1i1p1f1/Omon/o2/gn/v20190903/o2_Omon_IPSL-CM6A-LR_ssp585_r1i1p1f1_gn_220101-230012.nc']
<xarray.Dataset>
Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 3432, x: 362, y: 332)
Coordinates:
    nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
    nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
  * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
  * time            (time) object 2015-01-16T12:00:00 ... 2300-12-16 12:00:00
  * member_id       (member_id) <U8 'r1i1p1f1'
Dimensions without coordinates: axis_nbounds, nvertex, x, y
Data variables:
    olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
    time_bounds     (time, axis_nbounds) object dask.array<chunksize=(6, 2), meta=np.ndarray>
    bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
    bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>
Attributes:
    branch_time_in_parent:  60265.0
    parent_source_id:       IPSL-CM6A-LR
    frequency:              mon
    source_type:            AOGCM BGC
    realm:                  ocnBgchem
    branch_method:          standard
    sub_experiment_id:      none
    parent_variant_label:   r1i1p1f1
    description:            Future scenario with high radiative forcing by th...
    external_variables:     areacello volcello
    history:                none
    sub_experiment:         none
    branch_time_in_child:   0.0
    source:                 IPSL-CM6A-LR (2017):  atmos: LMDZ (NPv6, N96; 144...
    creation_date:          2019-08-22T22:26:32Z
    mip_era:                CMIP6
    intake_esm_varname:     o2
    forcing_index:          1
    name:                   /ccc/work/cont003/gencmip6/oboucher/IGCM_OUT/IPSL...
    grid:                   native ocean tri-polar grid with 105 k ocean cells
    parent_time_units:      days since 1850-01-01 00:00:00
    variable_id:            o2
    license:                CMIP6 model data produced by IPSL is licensed und...
    parent_activity_id:     CMIP
    nominal_resolution:     100 km
    experiment_id:          ssp585
    activity_id:            ScenarioMIP
    parent_mip_era:         CMIP6
    title:                  IPSL-CM6A-LR model output prepared for CMIP6 / Sc...
    product:                model-output
    further_info_url:       https://furtherinfo.es-doc.org/CMIP6.IPSL.IPSL-CM...
    institution_id:         IPSL
    variant_label:          r1i1p1f1
    data_specs_version:     01.00.28
    grid_label:             gn
    realization_index:      1
    tracking_id:            hdl:21.14100/dcd42bc5-cc58-4234-b58e-21e4b624ba04...
    institution:            Institut Pierre Simon Laplace, Paris 75252, France
    initialization_index:   1
    experiment:             update of RCP8.5 based on SSP5
    contact<EMAIL_ADDRESS>    dr2xml_md5sum:          c4b76079137f2c3b9298396d121b21c1
    table_id:               Omon
    source_id:              IPSL-CM6A-LR
    CMIP6_CV_version:       cv=<IP_ADDRESS>
    parent_experiment_id:   historical
    Conventions:            CF-1.7 CMIP-6.2
    physics_index:          1
    dr2xml_version:         1.16
    model_version:          6.1.8
    EXPID:                  ssp585
    variant_info:           Each member starts from the corresponding member ...
#####################r2i1p1f1##################
r2i1p1f1

--> The keys in the returned dictionary of datasets are constructed as follows:
	'activity_id.institution_id.source_id.experiment_id.table_id.grid_label'

--> There is/are 1 group(s)
True
1032/1032
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r2i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r2i1p1f1_gn_201501-210012.nc']
<xarray.Dataset>
Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 1032, x: 362, y: 332)
Coordinates:
    nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
    nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
  * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
  * time            (time) datetime64[ns] 2015-01-16T12:00:00 ... 2100-12-16T12:00:00
  * member_id       (member_id) <U8 'r2i1p1f1'
Dimensions without coordinates: axis_nbounds, nvertex, x, y
Data variables:
    olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
    time_bounds     (time, axis_nbounds) datetime64[ns] dask.array<chunksize=(6, 2), meta=np.ndarray>
    bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
    bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>
Attributes:
    name:                   /ccc/work/cont003/gencmip6/lurtont/IGCM_OUT/IPSLC...
    Conventions:            CF-1.7 CMIP-6.2
    creation_date:          2019-10-18T06:38:14Z
    tracking_id:            hdl:21.14100/d025e86c-aa6a-4d52-88ca-bc649f48233f
    description:            Future scenario with high radiative forcing by th...
    title:                  IPSL-CM6A-LR model output prepared for CMIP6 / Sc...
    activity_id:            ScenarioMIP
    contact<EMAIL_ADDRESS>    data_specs_version:     01.00.28
    dr2xml_version:         1.16
    experiment_id:          ssp585
    experiment:             update of RCP8.5 based on SSP5
    external_variables:     areacello volcello
    forcing_index:          1
    frequency:              mon
    further_info_url:       https://furtherinfo.es-doc.org/CMIP6.IPSL.IPSL-CM...
    grid:                   native ocean tri-polar grid with 105 k ocean cells
    grid_label:             gn
    nominal_resolution:     100 km
    history:                none
    initialization_index:   1
    institution_id:         IPSL
    institution:            Institut Pierre Simon Laplace, Paris 75252, France
    license:                CMIP6 model data produced by IPSL is licensed und...
    mip_era:                CMIP6
    parent_mip_era:         CMIP6
    parent_source_id:       IPSL-CM6A-LR
    parent_time_units:      days since 1850-01-01 00:00:00
    parent_variant_label:   r2i1p1f1
    branch_method:          standard
    branch_time_in_parent:  60265.0
    branch_time_in_child:   0.0
    physics_index:          1
    product:                model-output
    realization_index:      2
    realm:                  ocnBgchem
    source:                 IPSL-CM6A-LR (2017):  atmos: LMDZ (NPv6, N96; 144...
    source_id:              IPSL-CM6A-LR
    source_type:            AOGCM BGC
    sub_experiment_id:      none
    sub_experiment:         none
    table_id:               Omon
    variable_id:            o2
    variant_info:           Each member starts from the corresponding member ...
    variant_label:          r2i1p1f1
    EXPID:                  ssp585
    CMIP6_CV_version:       cv=<IP_ADDRESS>
    dr2xml_md5sum:          b6f602401512e82e2d7cadc2c6f36c2a
    model_version:          6.1.10
    parent_experiment_id:   historical
    parent_activity_id:     CMIP
    intake_esm_varname:     o2
#####################r3i1p1f1##################
r3i1p1f1

--> The keys in the returned dictionary of datasets are constructed as follows:
	'activity_id.institution_id.source_id.experiment_id.table_id.grid_label'

--> There is/are 1 group(s)
True
1032/1032
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r3i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r3i1p1f1_gn_201501-210012.nc']
<xarray.Dataset>
Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 1032, x: 362, y: 332)
Coordinates:
    nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
    nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
  * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
  * time            (time) datetime64[ns] 2015-01-16T12:00:00 ... 2100-12-16T12:00:00
  * member_id       (member_id) <U8 'r3i1p1f1'
Dimensions without coordinates: axis_nbounds, nvertex, x, y
Data variables:
    olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
    time_bounds     (time, axis_nbounds) datetime64[ns] dask.array<chunksize=(6, 2), meta=np.ndarray>
    bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
    bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>
Attributes:
    name:                   /ccc/work/cont003/gencmip6/lurtont/IGCM_OUT/IPSLC...
    Conventions:            CF-1.7 CMIP-6.2
    creation_date:          2019-10-22T12:30:57Z
    tracking_id:            hdl:21.14100/edb14fa8-7e14-466c-9c58-012c75147c94
    description:            Future scenario with high radiative forcing by th...
    title:                  IPSL-CM6A-LR model output prepared for CMIP6 / Sc...
    activity_id:            ScenarioMIP
    contact<EMAIL_ADDRESS>    data_specs_version:     01.00.28
    dr2xml_version:         1.16
    experiment_id:          ssp585
    experiment:             update of RCP8.5 based on SSP5
    external_variables:     areacello volcello
    forcing_index:          1
    frequency:              mon
    further_info_url:       https://furtherinfo.es-doc.org/CMIP6.IPSL.IPSL-CM...
    grid:                   native ocean tri-polar grid with 105 k ocean cells
    grid_label:             gn
    nominal_resolution:     100 km
    history:                none
    initialization_index:   1
    institution_id:         IPSL
    institution:            Institut Pierre Simon Laplace, Paris 75252, France
    license:                CMIP6 model data produced by IPSL is licensed und...
    mip_era:                CMIP6
    parent_mip_era:         CMIP6
    parent_source_id:       IPSL-CM6A-LR
    parent_time_units:      days since 1850-01-01 00:00:00
    parent_variant_label:   r3i1p1f1
    branch_method:          standard
    branch_time_in_parent:  60265.0
    branch_time_in_child:   0.0
    physics_index:          1
    product:                model-output
    realization_index:      3
    realm:                  ocnBgchem
    source:                 IPSL-CM6A-LR (2017):  atmos: LMDZ (NPv6, N96; 144...
    source_id:              IPSL-CM6A-LR
    source_type:            AOGCM BGC
    sub_experiment_id:      none
    sub_experiment:         none
    table_id:               Omon
    variable_id:            o2
    variant_info:           Each member starts from the corresponding member ...
    variant_label:          r3i1p1f1
    EXPID:                  ssp585
    CMIP6_CV_version:       cv=<IP_ADDRESS>
    dr2xml_md5sum:          b6f602401512e82e2d7cadc2c6f36c2a
    model_version:          6.1.10
    parent_experiment_id:   historical
    parent_activity_id:     CMIP
    intake_esm_varname:     o2
#####################r4i1p1f1##################
r4i1p1f1

--> The keys in the returned dictionary of datasets are constructed as follows:
	'activity_id.institution_id.source_id.experiment_id.table_id.grid_label'

--> There is/are 1 group(s)
True
1032/1032
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r4i1p1f1/Omon/o2/gn/v20191122/o2_Omon_IPSL-CM6A-LR_ssp585_r4i1p1f1_gn_201501-210012.nc']
<xarray.Dataset>
Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 1032, x: 362, y: 332)
Coordinates:
    nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
    nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
  * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
  * time            (time) datetime64[ns] 2015-01-16T12:00:00 ... 2100-12-16T12:00:00
  * member_id       (member_id) <U8 'r4i1p1f1'
Dimensions without coordinates: axis_nbounds, nvertex, x, y
Data variables:
    olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
    time_bounds     (time, axis_nbounds) datetime64[ns] dask.array<chunksize=(6, 2), meta=np.ndarray>
    bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
    bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>
Attributes:
    name:                   /ccc/work/cont003/gencmip6/dupontel/IGCM_OUT/IPSL...
    Conventions:            CF-1.7 CMIP-6.2
    creation_date:          2019-10-22T10:48:30Z
    tracking_id:            hdl:21.14100/2a4fb73b-f64c-46f5-81e2-4014c9505c26
    description:            Future scenario with high radiative forcing by th...
    title:                  IPSL-CM6A-LR model output prepared for CMIP6 / Sc...
    activity_id:            ScenarioMIP
    contact<EMAIL_ADDRESS>    data_specs_version:     01.00.28
    dr2xml_version:         1.16
    experiment_id:          ssp585
    experiment:             update of RCP8.5 based on SSP5
    external_variables:     areacello volcello
    forcing_index:          1
    frequency:              mon
    further_info_url:       https://furtherinfo.es-doc.org/CMIP6.IPSL.IPSL-CM...
    grid:                   native ocean tri-polar grid with 105 k ocean cells
    grid_label:             gn
    nominal_resolution:     100 km
    history:                none
    initialization_index:   1
    institution_id:         IPSL
    institution:            Institut Pierre Simon Laplace, Paris 75252, France
    license:                CMIP6 model data produced by IPSL is licensed und...
    mip_era:                CMIP6
    parent_mip_era:         CMIP6
    parent_source_id:       IPSL-CM6A-LR
    parent_time_units:      days since 1850-01-01 00:00:00
    parent_variant_label:   r4i1p1f1
    branch_method:          standard
    branch_time_in_parent:  60265.0
    branch_time_in_child:   0.0
    physics_index:          1
    product:                model-output
    realization_index:      4
    realm:                  ocnBgchem
    source:                 IPSL-CM6A-LR (2017):  atmos: LMDZ (NPv6, N96; 144...
    source_id:              IPSL-CM6A-LR
    source_type:            AOGCM BGC
    sub_experiment_id:      none
    sub_experiment:         none
    table_id:               Omon
    variable_id:            o2
    variant_info:           Each member starts from the corresponding member ...
    variant_label:          r4i1p1f1
    EXPID:                  ssp585
    CMIP6_CV_version:       cv=<IP_ADDRESS>
    dr2xml_md5sum:          b6f602401512e82e2d7cadc2c6f36c2a
    model_version:          6.1.10
    parent_experiment_id:   historical
    parent_activity_id:     CMIP
    intake_esm_varname:     o2
#####################r6i1p1f1##################
r6i1p1f1

--> The keys in the returned dictionary of datasets are constructed as follows:
	'activity_id.institution_id.source_id.experiment_id.table_id.grid_label'

--> There is/are 1 group(s)
True
1032/1032
['/tiger/scratch/gpfs/GEOCLIM/synda/data/CMIP6/ScenarioMIP/IPSL/IPSL-CM6A-LR/ssp585/r6i1p1f1/Omon/o2/gn/v20191121/o2_Omon_IPSL-CM6A-LR_ssp585_r6i1p1f1_gn_201501-210012.nc']
<xarray.Dataset>
Dimensions:         (axis_nbounds: 2, member_id: 1, nvertex: 4, olevel: 75, time: 1032, x: 362, y: 332)
Coordinates:
    nav_lat         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
    nav_lon         (y, x) float32 dask.array<chunksize=(332, 362), meta=np.ndarray>
  * olevel          (olevel) float32 0.50576 1.5558553 ... 5698.0605 5902.0576
  * time            (time) datetime64[ns] 2015-01-16T12:00:00 ... 2100-12-16T12:00:00
  * member_id       (member_id) <U8 'r6i1p1f1'
Dimensions without coordinates: axis_nbounds, nvertex, x, y
Data variables:
    olevel_bounds   (time, olevel, axis_nbounds) float32 dask.array<chunksize=(1032, 75, 2), meta=np.ndarray>
    time_bounds     (time, axis_nbounds) datetime64[ns] dask.array<chunksize=(6, 2), meta=np.ndarray>
    bounds_nav_lat  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    area            (time, y, x) float32 dask.array<chunksize=(1032, 332, 362), meta=np.ndarray>
    bounds_nav_lon  (time, y, x, nvertex) float32 dask.array<chunksize=(1032, 332, 362, 4), meta=np.ndarray>
    o2              (member_id, time, olevel, y, x) float32 dask.array<chunksize=(1, 6, 75, 332, 362), meta=np.ndarray>
Attributes:
    name:                   /ccc/work/cont003/gencmip6/lurtont/IGCM_OUT/IPSLC...
    Conventions:            CF-1.7 CMIP-6.2
    creation_date:          2019-10-22T10:17:28Z
    tracking_id:            hdl:21.14100/b7e9c317-cc62-4a89-b463-7c456231987d
    description:            Future scenario with high radiative forcing by th...
    title:                  IPSL-CM6A-LR model output prepared for CMIP6 / Sc...
    activity_id:            ScenarioMIP
    contact<EMAIL_ADDRESS>    data_specs_version:     01.00.28
    dr2xml_version:         1.16
    experiment_id:          ssp585
    experiment:             update of RCP8.5 based on SSP5
    external_variables:     areacello volcello
    forcing_index:          1
    frequency:              mon
    further_info_url:       https://furtherinfo.es-doc.org/CMIP6.IPSL.IPSL-CM...
    grid:                   native ocean tri-polar grid with 105 k ocean cells
    grid_label:             gn
    nominal_resolution:     100 km
    history:                none
    initialization_index:   1
    institution_id:         IPSL
    institution:            Institut Pierre Simon Laplace, Paris 75252, France
    license:                CMIP6 model data produced by IPSL is licensed und...
    mip_era:                CMIP6
    parent_mip_era:         CMIP6
    parent_source_id:       IPSL-CM6A-LR
    parent_time_units:      days since 1850-01-01 00:00:00
    parent_variant_label:   r6i1p1f1
    branch_method:          standard
    branch_time_in_parent:  60265.0
    branch_time_in_child:   0.0
    physics_index:          1
    product:                model-output
    realization_index:      6
    realm:                  ocnBgchem
    source:                 IPSL-CM6A-LR (2017):  atmos: LMDZ (NPv6, N96; 144...
    source_id:              IPSL-CM6A-LR
    source_type:            AOGCM BGC
    sub_experiment_id:      none
    sub_experiment:         none
    table_id:               Omon
    variable_id:            o2
    variant_info:           Each member starts from the corresponding member ...
    variant_label:          r6i1p1f1
    EXPID:                  ssp585
    CMIP6_CV_version:       cv=<IP_ADDRESS>
    dr2xml_md5sum:          b6f602401512e82e2d7cadc2c6f36c2a
    model_version:          6.1.10
    parent_experiment_id:   historical
    parent_activity_id:     CMIP
    intake_esm_varname:     o2

I really doesnt seem like there are duplicate times in these, unless I am missing something.

@andersy005 @jbusecke can we get on a quick video call? Julius, wanna send out a zoom invite?

will do in 5!

@andersy005 @jbusecke can we get on a quick video call? Julius, wanna send out a zoom invite?

Sure.
@jbusecke, @sherimickelson
I just found out that there's a bug in the _pick_latest_version(df) function. Since Pandas does not propagate missing values (NaN) when doing groupby() (See https://github.com/pandas-dev/pandas/issues/3729), the following code (in _pick_latest_version(df)) ends up returning 0 groups since the dcpp_init_year column has missing values.
grpby = list(set(df.columns.tolist()) - {'path', 'version'})
groups = df.groupby(grpby)

As a result, the subsequent code in _pick_latest_version(df) doesn't actually work as expected:(

Check your email for the invite.

As an update, we found out that the issue was stemming from differences in calendar units used in the netCDF files. These differences were causing xarray to fail since it was trying to mix time values decoded with pandas and cftime together.
Solution: Specify use_cftime=True parameter:
cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585',member_id='r1i1p1f1')
ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': True, 'use_cftime': True})

@jbusecke, let me know whether the solution I suggested above is accurate.

This still blows my notebook up (literally the whole thing, not just the kernel):

Note that I am aggregating all members.

The read in works as expected, but the plotting is still causing issues.
cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585')
ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': True, 'use_cftime': True})
ds = ddict['ScenarioMIP.IPSL.IPSL-CM6A-LR.ssp585.Omon.gn']
ds.o2.isel(time=-1, olevel=0).plot(col='member_id')

Could you try this modified example on the ncar netdcdfs, by any chance? I am curious if this is an oddity with the files (they are gigantic for IPSL), or our system in Princeton.

What does ds.o2 look like?

I can check that tomorrow. Cant afford another crash, since I have something else running.
It looked fine though. Perhaps it has to do with the chunks, I will try to test tomorrow.

Could you try this modified example on the ncar netdcdfs, by any chance? I am curious if this is an oddity with the files (they are gigantic for IPSL), or our system in Princeton.

I will give this a try on Cheyenne, and will let you know how it goes

What does ds.o2 look like?

Here's what I am getting:

When I tried executing ds.o2.isel(time=-1, olevel=0).plot(col='member_id')

I got the following error ( I don't understand what's going on)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-2286abd5dbfc> in <module>
----> 1 ds.o2.isel(time=-1, olevel=0).plot(col='member_id')

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/plot/plot.py in __call__(self, **kwargs)
    444
    445     def __call__(self, **kwargs):
--> 446         return plot(self._da, **kwargs)
    447
    448     @functools.wraps(hist)

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/plot/plot.py in plot(darray, row, col, col_wrap, ax, hue, rtol, subplot_kws, **kwargs)
    198     kwargs["ax"] = ax
    199
--> 200     return plotfunc(darray, **kwargs)
    201
    202

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/plot/plot.py in newplotfunc(darray, x, y, figsize, size, aspect, ax, row, col, col_wrap, xincrease, yincrease, add_colorbar, add_labels, vmin, vmax, cmap, center, robust, extend, levels, infer_intervals, colors, subplot_kws, cbar_ax, cbar_kwargs, xscale, yscale, xticks, yticks, xlim, ylim, norm, **kwargs)
    631             # Need the decorated plotting function
    632             allargs["plotfunc"] = globals()[plotfunc.__name__]
--> 633             return _easy_facetgrid(darray, kind="dataarray", **allargs)
    634
    635         plt = import_matplotlib_pyplot()

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/plot/facetgrid.py in _easy_facetgrid(data, plotfunc, kind, x, y, row, col, col_wrap, sharex, sharey, aspect, size, subplot_kws, ax, figsize, **kwargs)
    623         raise ValueError("cannot provide both `figsize` and `size` arguments")
    624
--> 625     g = FacetGrid(
    626         data=data,
    627         col=col,

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/plot/facetgrid.py in __init__(self, data, col, row, col_wrap, sharex, sharey, figsize, aspect, size, subplot_kws)
    117
    118         # Handle corner case of nonunique coordinates
--> 119         rep_col = col is not None and not data[col].to_index().is_unique
    120         rep_row = row is not None and not data[row].to_index().is_unique
    121         if rep_col or rep_row:

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/core/dataarray.py in to_index(self)
    570         arrays.
    571         """
--> 572         return self.variable.to_index()
    573
    574     @property

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/core/variable.py in to_index(self)
    468     def to_index(self):
    469         """Convert this variable to a pandas.Index"""
--> 470         return self.to_index_variable().to_index()
    471
    472     def to_dict(self, data=True):

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/core/variable.py in to_index_variable(self)
    460     def to_index_variable(self):
    461         """Return this variable as an xarray.IndexVariable"""
--> 462         return IndexVariable(
    463             self.dims, self._data, self._attrs, encoding=self._encoding, fastpath=True
    464         )

/glade/work/abanihi/softwares/miniconda3/envs/lens-conversion/lib/python3.8/site-packages/xarray/core/variable.py in __init__(self, dims, data, attrs, encoding, fastpath)
   2086         super().__init__(dims, data, attrs, encoding, fastpath)
   2087         if self.ndim != 1:
-> 2088             raise ValueError("%s objects must be 1-dimensional" % type(self).__name__)
   2089
   2090         # Unlike in Variable, always eagerly load values into memory

ValueError: IndexVariable objects must be 1-dimensional

The dataarray in questions looks like this:

Any way, I made some changes to the plotting command and I got everything to work (my kernel didn't die :)):

When I tried executing ds.o2.isel(time=-1, olevel=0).plot(col='member_id')

I believe this is only a single member dataset. My kernel dies when I try to do this plot command with several aggregated members. I assume that something happens during the aggregation of the (different length) members?

I can look into it if you can provide an example notebook. Aren't these datasets all on glade too?

This should reproduce it if you have an intake catalog set up that has the full data ( I was hoping this is the case on glade).(The cloud data is truncated).
import xarray as xr
import intake

col = intake.intake.open_esm_datastore(...)
cat = col.search(source_id='IPSL-CM6A-LR', variable_id='o2', experiment_id='ssp585')
ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': True, 'use_cftime': True})
ds = ddict['ScenarioMIP.IPSL.IPSL-CM6A-LR.ssp585.Omon.gn']
ds.o2.isel(time=-1, olevel=0).plot(col='member_id')

I have found an intermediate solution for this by modifying the preprocess function to chop of any time values that go beyond 2100:
def preprocess(ds):
    ds = ds.copy()
    if 'ssp' in ds.attrs['experiment_id']:
        ds = ds.sel(time=slice(None, '2100'))
    return ds

If you replace the above line with ddict = cat.to_dataset_dict(cdf_kwargs={'chunks': {'time':6},'decode_times': True, 'use_cftime': True}, preprocess=preprocess) this should work without crashing.
Hopefully this problem can be fixed upstream, since this basically discards those data. But I thought I post it for anyone who might have the same problem

I am running into this problem again and again. Since it seems the upstream fix seems to not be super straight forward, I was wondering if we could alleviate the situation with some additional functionality here.
In most cases, the problem is caused by 1-2 members that are significantly shorter or longer than the others. I would be ok to ditch these for now and continue the analysis with fewer members until the problem is fixed upstream.
Is there a way to evaluate the dimension shape of all datasets before they are combined alnong a specific dimension (e.g. member_id) and have an option like drop_time_mismatch='member_id', to eliminate the ones that do not agree with the majority size (the length of the time dimension found most often in the pool of members?).

Just blew up another notebook kernel of mine. Ill try to come up with a manual fix for now.
I was thinking along these lines:

Get full df from esm-datastore
Groupby each row except for member_id (I am working on zarr stores that have already been concatenated in time)
Check dimensionality for each store, pick the most common set of dimensions
Discard other members from dataframe
Replace the dataframe and read in as usual.

I can report back once I get this working. Any comments are much appreciated.

Dask will fix this: https://github.com/dask/dask/pull/6514

Should be fixed in the dask release this Friday. Julius, please reopen if you run into it again.

Dooooope! Thanks so much. Ill check on it this week for sure.


WorkflowLock.tryLock should not create a timer if the lock is available

When there's a call to WorkflowLock.tryLock(timeout, condition) , even if the lock is available - a new timer is created and saved to WF history (which can potentially affect performance and probably costs in temporal cloud)
Is there any particular reason that this method doesn't try to short-circuit execution (i.e. do not call Workflow.await) if the lock is already available (so unblock condition is already true)?...
This is actually a general question for Workflow.await as well ...

I agree that Workflow.await shouldn't create a timer ifthe  condition is immediately satisfied.

I agree that Workflow.await shouldn't create a timer if the condition is immediately satisfied.

Second, there is already another open issue that will cover this change.

Closing as a duplicate because there is already an issue to track the change to Workflow.await


People are invisible????

So i was playing sm64js as usual and I joined bomb omb battlefield as usual but unlike the usual there was nobody even though I want to them on the minimap and there was a floating flag! I picked up the flag after that and my friend joined and he saw a floating flag too! It's clear I am not the only one effected by this, can someone tell me why this is happening?

ya... its that dev thing again where they are working on the game??

can anyone confirm whether this issue still exists?

can anyone confirm whether this issue still exists?

Duplicate #163


The latest version as After updating the plug-in, the code cannot be automatically completed.

Describe the bug:
The latest version as After updating the plug-in, the code cannot be automatically completed.
Steps to reproduce:
After updating the plug-in, the code cannot be automatically completed, and the Live Templates in the settings have disappeared and are unavailable, as shown in the figure below:

Expected behavior:
Code completion can be performed normally
Additional context:
It works normally after disabling the plug-in:

嘿@Heart-Beats 非常感谢您提出这个问题！该问题已在 1.1.3 中修复，现已提交审批:) 审批通常需要一两天的时间，但如果您想手动获取工件，可以访问发布页面
一旦新版本获得批准并在 Marketplace 中提供，我将通过评论关闭该问题

I updated to the latest version in the Marketplace and the problem has been resolved

Thanks for confirming :)


[News display: list view] The 'Greencity' application url can not be opened in Internet Explorer

Environment:
Microsoft Windows 10 Home, Version 10.0.19041
Internet Explorer Version 11.630.19041.0
Reproducible: always
Build found: 2020-11-22
Preconditions
Internet Explorer browser should be opened
Steps to reproduce

Go to https://ita-social-projects.github.io/GreenCityClient/
Pay attention to the result

Actual result
The site is not displayed

Expected result
The site is displayed
User story and test case links
E.g.: "User story #460
Test case, (https://jira.softserve.academy/browse/GC-704)
(https://jira.softserve.academy/browse/GC-706)
(https://jira.softserve.academy/browse/GC-707)
(https://jira.softserve.academy/browse/GC-708)
(https://jira.softserve.academy/browse/GC-710)
(https://jira.softserve.academy/browse/GC-720)
(https://jira.softserve.academy/browse/GC-722)
(https://jira.softserve.academy/browse/GC-723)
(https://jira.softserve.academy/browse/GC-724)
(https://jira.softserve.academy/browse/GC-725)
(https://jira.softserve.academy/browse/GC-332)
(https://jira.softserve.academy/browse/GC-352)

we are not supporting IE


Batch commands for remote execution

See original issue on GitLab
In GitLab by [Gitlab user @juergbi] on Sep 25, 2018, 09:39
Background
The remote execution currently issues a separate remote action for each Sandbox.run() call. E.g., for BuildElements this means that each configure, build, install and strip command is executed separately. This approach has the following issues:

As file timestamps are not preserved in CAS, each command starts execution with the same timestamp for all staged files. Some projects such as cairo fail to build if the timestamps are not preserved between configure and make
Executing a command on a remote worker has an overhead. While we aim to keep this overhead as small as possible, the overall build time for an element is longer with the current individual issuing of commands

Task description
As already contemplated in the original Proposal for Remote Execution, a way to solve these issues is to allow plugins to batch commands, i.e., group multiple Sandbox.run() calls together. This requires designing an extension to the public plugin-facing API.

In GitLab by [Gitlab user @juergbi] on Oct 31, 2018, 10:22
mentioned in merge request !915

In GitLab by [Gitlab user @jjardon] on Nov 13, 2018, 17:06
Marking as blocker as this one is one of the features we agreed we want to try to have for 1.4

In GitLab by [Gitlab user @juergbi] on Nov 14, 2018, 10:28
mentioned in merge request !951

In GitLab by [Gitlab user @juergbi] on Nov 27, 2018, 14:16
closed via merge request !915

In GitLab by [Gitlab user @juergbi] on Nov 27, 2018, 14:16
mentioned in commit 127d332f33e0badbba3526548d9089640ee95ed1


Meta-121 crosslinks

@lennertvandevelde this is looking good! The ony thing I would suggest is to change the crosslink config format to a less error-prone syntax like json or yaml like { "name":[file1, file2]}

@lennertvandevelde this is looking good! The ony thing I would suggest is to change the crosslink config format to a less error-prone syntax like json or yaml like { "name":[file1, file2]}
Is this CLI argument pointing to a file or is the value supposed to be given inline?

Right now it is supposed to be given inline, but with different formats I would let it point to a file to keep the command a bit clear.

Ah I see, then the syntax is fine (You can consider doing name=file1;file2 to make it a bit more clear).
And is it then --crosslinks "name1;file1;file2;..." --crosslinks "name2;file3;file4;..." or --crosslinks "name1;file1;file2;... \n name2;file3;file4;..."

The latter form should be used now. I will however try and change some more things of the syntax, because unquoted, bash interprets the ';' as a newline.


Add basic documentation

How to connect
what is the uri
how to create a table
how to add data to a table
what must the data input look like
how do you open an existing table

completed


Improve ndjson-map documentation

I've found ndjson-cli to be really useful in the context of dealing with ElasticSearch records, which bulk import in ndjson format. One task I frequently find myself needing to do (and which might also be relevant for handling ndjson in the context of topojson files) is to add a constant to each record.
I've found you can do this with the following syntax:
cat output.ldj | ndjson-map 'd["@imported-from"] = "file-dump", d'

But it took me a bit of experimenting to figure that out. Might it be worth adding a few notes on syntax to the README, or perhaps the cli --help docs? Happy to contribute if so!

Yes. I welcome documentation improvements. Please send a PR and we can discuss.


Only consider a subnet as queried on the same network interface

Otherwise in case multiple network interfaces are present, not all interfaces may be queried and thus services will be removed too early.
I was seeing service removals for services shown as online by other queriers like avahi or python zeroconf. And i was able to track  it down to this.

The issue becomes more prominent in a IPv6 link local only setup. As all link local addresses are in the same subnet.

There is another occasion of a subnet_set in the code at https://github.com/keepsimple1/mdns-sd/blob/main/src/service_daemon.rs#L1204, perhaps it makes sense to use the same approach also while sending unsolicited_R responses. Please let me know whether the fix is also required there.

Tested this change in a pre-release version of https://github.com/hrzlgnm/mdns-browser in my setup where the issue was very prominent and drinving me crazy. And I could not observe it anymore.

Perhaps we only need to handle ipv6 link local adresses in special manner, so the subnect optimization for other address kinds still works.

Let's put it this way:
Each network interface on a device gets a unique link-local address. Even if two interfaces are on the same physical network, their link-local addresses are treated as being on separate links.Therefore, link-local addresses from different interfaces or devices are not considered to be in the same subnet in the traditional sense, even if they are on the same physical network segment.

If I understand, the problem is that link-local addresses (especially for IPv6 as every IPv6 interface has a link-local address) do not belong to the same network segment even though their netmask (i.e. prefix) match.
In other words, we should not use "subnet" to filter out any link-local addresses. But we can (probably should?) still filter regular non-link-local addresses of the same subnet (even though that might not be very common).
From this perspective, I have a different take about the implementation of the fix, and came up with a diff like this:  (in both places where ifaddr_subnet was used)
diff --git a/src/service_daemon.rs b/src/service_daemon.rs
index 8ed4c8c..f06100b 100644
--- a/src/service_daemon.rs
+++ b/src/service_daemon.rs
@@ -1205,11 +1205,15 @@ impl Zeroconf {

         for (_, intf_sock) in self.intf_socks.iter() {
             let subnet = ifaddr_subnet(&intf_sock.intf.addr);
-            if subnet_set.contains(&subnet) {
-                continue; // no need to send again in the same subnet.
+            if !intf_sock.intf.is_link_local() {
+                if subnet_set.contains(&subnet) {
+                    continue; // no need to send again in the same subnet.
+                }
             }
             if self.broadcast_service_on_intf(info, intf_sock) {
-                subnet_set.insert(subnet);
+                if !intf_sock.intf.is_link_local() {
+                    subnet_set.insert(subnet);
+                }
                 outgoing_addrs.push(intf_sock.intf.ip());
             }
         }
@@ -1400,11 +1404,13 @@ impl Zeroconf {

         let mut subnet_set: HashSet<u128> = HashSet::new();
         for (_, intf_sock) in self.intf_socks.iter() {
-            let subnet = ifaddr_subnet(&intf_sock.intf.addr);
-            if subnet_set.contains(&subnet) {
-                continue; // no need to send query the same subnet again.
+            if !intf_sock.intf.is_link_local() {
+                let subnet = ifaddr_subnet(&intf_sock.intf.addr);
+                if subnet_set.contains(&subnet) {
+                    continue; // no need to send query the same subnet again.
+                }
+                subnet_set.insert(subnet);
             }
-            subnet_set.insert(subnet);
             broadcast_dns_on_intf(&out, intf_sock);
         }
     }

Does it make sense? Will it help address your case?

If I understand, the problem is that link-local addresses (especially for IPv6 as every IPv6 interface has a link-local address) do not belong to the same network segment even though their netmask (i.e. prefix) match.
In other words, we should not use "subnet" to filter out any link-local addresses. But we can (probably should?) still filter regular non-link-local addresses of the same subnet (even though that might not be very common).
From this perspective, I have a different take about the implementation of the fix, and came up with a diff like this: (in both places where ifaddr_subnet was used)
diff --git a/src/service_daemon.rs b/src/service_daemon.rs
index 8ed4c8c..f06100b 100644
--- a/src/service_daemon.rs
+++ b/src/service_daemon.rs
@@ -1205,11 +1205,15 @@ impl Zeroconf {

         for (_, intf_sock) in self.intf_socks.iter() {
             let subnet = ifaddr_subnet(&intf_sock.intf.addr);
-            if subnet_set.contains(&subnet) {
-                continue; // no need to send again in the same subnet.
+            if !intf_sock.intf.is_link_local() {
+                if subnet_set.contains(&subnet) {
+                    continue; // no need to send again in the same subnet.
+                }
             }
             if self.broadcast_service_on_intf(info, intf_sock) {
-                subnet_set.insert(subnet);
+                if !intf_sock.intf.is_link_local() {
+                    subnet_set.insert(subnet);
+                }
                 outgoing_addrs.push(intf_sock.intf.ip());
             }
         }
@@ -1400,11 +1404,13 @@ impl Zeroconf {

         let mut subnet_set: HashSet<u128> = HashSet::new();
         for (_, intf_sock) in self.intf_socks.iter() {
-            let subnet = ifaddr_subnet(&intf_sock.intf.addr);
-            if subnet_set.contains(&subnet) {
-                continue; // no need to send query the same subnet again.
+            if !intf_sock.intf.is_link_local() {
+                let subnet = ifaddr_subnet(&intf_sock.intf.addr);
+                if subnet_set.contains(&subnet) {
+                    continue; // no need to send query the same subnet again.
+                }
+                subnet_set.insert(subnet);
             }
-            subnet_set.insert(subnet);
             broadcast_dns_on_intf(&out, intf_sock);
         }
     }

Does it make sense? Will it help address your case?

Yes makes sense, I'll check it out on my branch and test whether this works for me.

(and thanks for your PR and investigations!)
Glad to use the library and happy to contribute to. ❤

I've tested my latest change again with another pre-release version of mdns-browser and it works with your suggested changeg.
Thanks for you feedback.

Thanks for updating and verifying! Will merge now.


fix(knex): fix $or over 1:m and m:1 auto-joined relations

Fixes #3301

Codecov Report

Merging #3307 (20595bb) into master (f0bc261) will not change coverage.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##            master     #3307   +/-   ##
=========================================
  Coverage   100.00%   100.00%
=========================================
  Files          194       194
  Lines        12136     12145    +9
  Branches      2818      2822    +4
=========================================
+ Hits         12136     12145    +9

Impacted Files
Coverage Δ

packages/knex/src/query/ObjectCriteriaNode.ts
100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f0bc261...20595bb. Read the comment docs.


Automated cherry pick of #5505

Cherry pick of #5505 on release-1.45.
/cc  @enahum

/release-note-none


Click events are not triggered when widget is wrapped with a Badge

Steps to reproduce

Run the example code
Click on the badge on Text1
Long press the badge on Text2

Expected results
Clicking on the badge of Text1 will print "IconButton".
Long pressing the badge of Text2 will show the tooltip.
Actual results
Nothing happens.
Code sample
Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Badge(
                label: IconButton(
                  onPressed: () => print('IconButton'),
                  icon: const Icon(Icons.ads_click),
                ),
                backgroundColor: Colors.transparent,
                child: const Text('Text1'),
              ),
              const SizedBox(height: 20),
              const Badge(
                label: Tooltip(
                  message: 'Tooltip',
                  child: Icon(Icons.ads_click),
                ),
                backgroundColor: Colors.transparent,
                child: Text('Text2'),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Screenshots or Video
No response
Logs
No response
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.24.2, on macOS 14.6.1 23G93 darwin-x64, locale de-DE)
    • Flutter version 3.24.2 on channel stable at /Users/huynh/.asdf/installs/flutter/3.24.2-stable
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4cf269e36d (vor 2 Wochen), 2024-09-03 14:30:00 -0700
    • Engine revision a6bd3f1de1
    • Dart version 3.5.2
    • DevTools version 2.37.2

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/huynh/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • ANDROID_HOME = /Users/huynh/Library/Android/sdk
    • Java binary at: /Users/huynh/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15F31d
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.1)
    • Android Studio at /Users/huynh/Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)

[✓] IntelliJ IDEA Ultimate Edition (version 2024.2.1)
    • IntelliJ at /Users/huynh/Applications/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 81.1.3
    • Dart plugin version 242.21829.3

[✓] VS Code (version 1.92.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.94.0

[✓] Connected device (3 available)
    • iPhone 13 mini (mobile) • 9EC9B697-54E5-49AB-9F44-4D997DFDBE20 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-17-5 (simulator)
    • macOS (desktop)         • macos                                • darwin-x64     • macOS 14.6.1 23G93 darwin-x64
    • Chrome (web)            • chrome                               • web-javascript • Google Chrome 128.0.6613.138

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Hi @ngoc-quoc-huynh, the typical usage of the Badge widget is to make the child rather then clickable item and have the label display some information related to that item. Is there any reason in particular you have reversed this?

Oh I didn't know that. I was just testing around.

Closing this as solved based on https://github.com/flutter/flutter/issues/155300#issuecomment-2357668717


feat: new home page copy

:tada: This PR is included in version 1.5.0 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


chore: Update dependencies for gax

There are two main reasons for this PR.

There was a security problem reported in https://github.com/googleapis/elixir-google-api/pull/10753 that seems to have gone stale. This PR does the same change for gax.
Because the dependencies in gax are old they are preventing some newer dependencies in our project (a combination of tesla, gun, mime).

Hey 👋 will this PR be eventually merged?

@dazuma would it be possible to get this pushed the rest of the way through? It would be helpful to have these dependencies updated both for security and for interoperability. It's been approved, so I'm not sure what the next step is to have it merged.


Safari: anime.setDashoffset causes "getTotalLength is not a function" error on svg circle element

Example:
http://codepen.io/anon/pen/KWbBmy

I've got a working fix specifically for circles... will elaborate to support other shapes and submit a PR later when I've got some time. Proposed fix:
  function setDashoffsetCircle(el) {
    var length = 2 * Math.PI * el.getAttribute('r');
    el.setAttribute('stroke-dasharray', length);
    return length;
  }

I have this error too.
Reason for this error:
https://github.com/juliangarnier/anime/issues/155

Got the same problem:
http://jeroen.no

By looking at the problem did I find a way to solve it. By integrating a check if the given element is a "SVGLineElement" to the setDashoffset function.
function dist(x1, x2, y1, y2){
  return Math.sqrt( (x2-=x1)*x2 + (y2-=y1)*y2 );
}

function setDashoffset(el) {
  const isLine = el instanceof SVGLineElement;
  const pathLength = isLine ? dist(el.x1.baseVal.value, el.x2.baseVal.value, el.y1.baseVal.value, el.y2.baseVal.value) : el.getTotalLength();
  el.setAttribute('stroke-dasharray', pathLength);
  return pathLength;
}

SVGLineElement is supported by all modern browsers.


Standups not saved in redis

Hi, is there any extra configuration needed for standups to be saved on redis ?

@RaNd250 Did you solve this? Standups are not persisted for me as well.


integration testing

https://github.com/airavata-courses/CloudElves/commit/bf0f5d291024a564ac50820b4908d1ffd0ffb662
https://github.com/airavata-courses/CloudElves/commit/391b84785639d084af2b9aedf19b785c76880ee4
https://github.com/airavata-courses/CloudElves/commit/1a01367847d92fbbbcbdb8925fcb43e4f92958b3
https://github.com/airavata-courses/CloudElves/commit/7b7862aa7d61ada1ca3d60c230033fc8f65ba3af


Only one account can log in

these are my version about my win10 and software

all green but only one account can log how to deal with it. Thank you!

don't forget : the last line of the .ini must be a one blank line.

don't forget : the last line of the .ini must be a one blank line.

yes it is

Try convert your .ini from Unix to ANSI

Try convert your .ini from Unix to ANSI

no,it doesn't work

could anyone help me =_=?

Are you using the same user account to login because it looks like you have the "Single session per user" checked...

Are you using the same user account to login because it looks like you have the "Single session per user" checked...

I have three acount,it still remind me only one account can sign in, and another account will offline.

Try to taskkill termservice

Try to taskkill termservice

i did that and the software were red

Add users to RDP group


Grid component example: Show "no values" when table is empty ?

Suggestion for improvement:
https://jsfiddle.net/kaihendry/xkkbfL3L/361/
Or is there a better suggestion?

Thank you for your commenting!
Grid component is demonstration that using Component, v-for and filter.
In the example, I think that don't need to include about no values to make it simple.

Yeah, I agree with @kazupon that this is fine the way it is. All these examples could have more features added to them, but then it would be more difficult to see the specific features being highlighted.


When click on start now for free button white header not disappear when you scroll up

bug appears in safari


Syhol: mise-vscode

I started working on a VSCode extension for mise a while back but it didn't go anywhere, feel free to take any bits from it:
https://github.com/syhol/mise-vscode
I doubt I'll develop it any further and its totally undocumented. I just wanted to share it in case you might get some use out of it.
I love the look of your project and I look forward to seeing it develop further.

Thank you! I looked at the VSCode marketplace and the existing ones looked like POC, so I created this one. I feel like having an easy way to find where a tool/task is defined might make the adoption of mise easier.
I will integrate some features are present in your plugin like automatic configuration for bun/ruff/go/deno etc. I am also adding automatic change detection so that one does not have to manually reload the mise panels. Adding a mise install prompt if some tools are missing is also on my list
Please let me know if there are any features that you would like to see


Add replace option and JSONMessage#from

It would be nice to have a JSONMessage#replace(String, String/Object) method witch would replace any appearance of the target String with the provided String/Object (Whichever goes better).
Additionally would a JSONMessage#from(String) sure be useful too. This would essentially attempt to parse the provided String into a JSONMessage object (Essentially parsing JSON to a JSONMessage object when possible).
I currently try to implement JSONMessage into a plugin, but this requires me to replace placeholders, which I can't all just replace before the JSONMessage#then(String) method, so I have to use an own ReflectionHelper class to send the message as BungeeCord's ComponentSerializer seems to be utter trash.
Perhaps another alternative would be a String field for the JSONMessage#send(Player...) method? Like JSONMessage#send(String, Player...) which would take the String and send it to the players.

@Andre601 just to clarify, i want to make sure i understand what you're trying to do... so actually three new methods are being proposed:
JSONMessage#replace(String, String) - is this one beneficial at all? can just be achieved with String#replace on the string you input into the JSONMessage
JSONMessage#replace(String, JSONMessage) - is this meant so you could, for example, replace %player% with a player's name, but also give it its own styling & make it hoverable/clickable or something along those lines?
JSONMessage#fromJson(String) - I am using the name #fromJson rather than #from because i believe this is your intention -- to be able to load a serialized JSONMessage back into JSONMessage? what's the usecase for this one? being able to have configurable JSONMessages or something / read JSONMessages from a config?

JSONMessage#replace(String, String) - is this one beneficial at all? can just be achieved with String#replace on the string you input into the JSONMessage

I just mentioned it in my message that I can't just do a String#replace every time I add a new JSON part, since some require stuff such as the player which at the time of creating the JSONMessage isn't available.

JSONMessage#replace(String, JSONMessage) - is this meant so you could, for example, replace %player% with a player's name, but also give it its own styling & make it hoverable/clickable or something along those lines?

I never suggested this type of message.
I suggeated a static send method that would accept a JSONMessage (or perhaps also a String) to send.

JSONMessage#fromJson(String) - I am using the name #fromJson rather than #from because i believe this is your intention -- to be able to load a serialized JSONMessage back into JSONMessage? what's the usecase for this one? being able to have configurable JSONMessages or something / read JSONMessages from a config?

Yeah kind of.
In my case do I have to serialize the JSON into a String, to then replace specific placeholders.
And since I currently can't just generate a JSONMessage from a String is the only alternative to send the String using my own ReflectionHelper instance.

I just mentioned it in my message that I can't just do a String#replace every time I add a new JSON part, since some require stuff such as the player which at the time of creating the JSONMessage isn't available.
Why? Why not make a JSONMessage per player and send it only to that player? There seems to be some context I am missing, maybe a usage example would help clear it up?

I suggeated a static send method that would accept a JSONMessage (or perhaps also a String) to send.
I didn't quite understand what "also" means here - what would that String do? Is that a replacement for:

JsonMessage.fromMinecraftJson(String).send(player)

?

In my case do I have to serialize the JSON into a String, to then replace specific placeholders.
Why can you only replace them in the generated JSON?

I just mentioned it in my message that I can't just do a String#replace every time I add a new JSON part, since some require stuff such as the player which at the time of creating the JSONMessage isn't available.

one other thing to add to this is that what you're suggesting here is inherently almost impossible due to the fact that all the JSONMessage methods mutate your instance, meaning you couldn't just create one instance and use it for each player, only replacing the placeholders for each player before sending. the first time you call JSONMessage#replace, your base message would be mutated and no longer usable for other players.
i think the issue here lies in your usage pattern of JSONMessage, rather than in JSONMessage's capabilities. however, doing what you requested with replacing placeholders in JSONMessage itself would definitely be possible -- it just wouldn't solve the problem you're trying to solve (which again, is a problem in your usage pattern)
for what it's worth, there is almost no difference in performance between creating JSONMessage objects for each player (to handle player-specific placeholders) vs creating one JSONMessage and sending it to a list of players. there's a difference, but not one that matters for 99.98% of use-cases.
the rest @I-Al-Istannen has covered quite nicely so i will not reiterate his points :smile:

I have it setup, where I pre-load/build the JSON instances, since I see 0 benefit in always making it yet again each time a player sends a message.
And since the information is (mostly) the sender of the message is a single replacement here often the easiest solution for me.
It would be (at least) useful to have the send alternative, where you could provide a JSON String. That would allow me to easly get the JSON String, replace any placeholders within it and then send it to all players, without the annoyance of having my own ReflectionHelper class just for that.
Also, I use JSONMessage in my plugin HexChat to provide JSON support:
https://github.com/Andre601/HexChat

I have it setup, where I pre-load/build the JSON instances, since I see 0 benefit in always making it yet again each time a player sends a message.

this isn't about whether it's beneficial or not, but rather whether it's necessary or not -- and in this case, it is. your usage pattern is fundamentally contrary to how JSONMessage works, because each message is mutable and therefore any customization per-player MUST require a separate JSONMessage object to be created for each player. (yes, if JSONMessage had a proper .clone() method, you could still kinda do what you're trying to do even with JSONMessages being mutable, but it doesn't)
the send alternative is redundant if you can parse JSON strings into a JSONMessage object, and then just send from there. send is definitely not the place to add complexity to.
i fully support the ability to serialize & deserialize JSONMessage objects, I can see a lot of potential benefits for that, but your given use case is not one of them but is rather a hack to get around the fact that there is no proper .clone() on JSONMessage and you don't wish to create a separate instance for each player.
optimally, I think moving to an immutable system in some kind of v2 rewrite would be nice, although it's too drastic of a rewrite for this current version. i think that the loading from JSON strings is a beneficial feature, as is being able to replace placeholders with custom JSONMessage objects (so that placeholders could be easily styled / have tooltips / etc).
but particularly for your use case, the best option would be to simply implement a proper JSONMessage#clone() method, as well as replace methods. that way you can construct your "base" JSONMessage, and then for each player just .clone() it and then .replace all the placeholders, then send it to that player (then rinse and repeat for each player you wish to send this to)


my side of the story

Finished!

Thanks for your contribution! Scenario A completed! See canvas for results


rename table command for oracle database

connect to oracle database
select a table in the tree
press F2, enter new name, save
The result SQL would look like

RENAME TABLE OLDTABLE TO "NEWTABLE";
That doesn't work for oracle - the word "table" must not be there:
RENAME OLDTABLE TO "NEWTABLE";

Thanks for report


Support client-side discovery of Settings and Inbox containers

Discovery of the Profile resource is already supported.
Extend to allow client-side discovery of the rest of the Default Containers (Inbox, Settings, root storage)

Parent issue: https://github.com/solid/solid/issues/23

Implemented in PR #33, closing.


ENH: Settle time for all positioners, and more

Proposed fix for #279
settle_time is added at the lowest level possible, making it possible to use throughout the hierarchy.
I think this is the cleanest it can possibly be done. Commence the bikeshedding.
If we can agree this isn't a terrible idea, I'll add it to Device as a kwarg as well.

cc @ambarb; we're working on it.

What about putting the settle time in MoveStatus but not StatusBase? Now I recuse myself from the discussion because there's a nasty rebase in the balance, and I am an interested party. ;- )

@danielballan that's definitely an option. A reason for shoving it in the base is to allow Devices to have a settling time as well. Device.set() would return a DeviceStatus or some subclass of StatusBase/DeviceStatus, but likely not a MoveStatus.

I think this is reasonable.  It makes sense that devices (not scans) know how long they need to settle.  Long term we need to work out a way to communicate to the run engine that it needs to add a sleep in after this move (which may be by plans asking motors if they have a settle time?) but :+1: for now.

I believe this is ready, broken tests were fixed. Merge at will.

@dchabot The idea would be to move the sleep out of a thread on to the asycio event loop so it would be an either-or setting.  Same with my desire to move the timeout logic on to a call_later  task on the event loop.


Adding other delimiters for the CSVOptions

Can you consider adding a semi colon delimiter or other delimiters on CSVOptions, currently only supporting "," and "/tab"

if co.Delimiter != "," && co.Delimiter != "\t" {
		return nil, errors.New("invalid delimiter type")
	}

Sure submit a pr and ill get it merged in

added will go out in new release


Exif Getting Multiple Info

Thanks for the adding the exif info.
before, i just dict each tags i need instead using "Exif" .Exif.Tags in init.html, because i have no idea how to parse ExposureTime|*big.Rat":"1/100 or "FocalLengthIn35mmFilm|int":"28" using javascript. 🤣
And I'm imagining the exif info will be on top / bottom of the image (just like the other lightbox)
never thought about showing on overlay like this.. 👍

So i'm testing the exif updates,
and modify the exif part from the config.toml into:
includeFields  = 'Artist|Make|Model|LensModel|FocalLength|FNumber|ExposureTime'
and the exif info is showing more tags because of the 'almost same' tags.. (i dont know how to say it correctly)
{"Exif":{"Lat":0,"Long":0,"Date":"2022-10-01T12:16:39+07:00","Tags":{"ExposureTime|*big.Rat":"1/100","FNumber":1.9,"FocalLength":3.7,"FocalLengthIn35mmFilm|int":"28","Make":"samsung","MakerNote":"0100 Z@P","Model":"SM-A710F"}}}
this is the content of json file.
maybe because i put the "FocalLength", so the "FocalLength" and the "FocalLengthIn35mmFilm" is inserted too..
and "Make" is almost the same with "MakerNote" ..
this is the screenshoot:

test url: https://splendid-pastelito-2af510.netlify.app/
test repo: https://github.com/andremoreno/gallerydeluxe
once again thank you..

includeFields/excludeFields takes a regexp, you need to find an expression that only matches what you want, e.g. Focal Length$